<!DOCTYPE html>


<html lang="zh-CN">


<head>
  <meta charset="utf-8" />
    
  <meta name="description" content="迎着朝阳的博客" />
  
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
  <title>
    spring核心之依赖注入 |  迎着朝阳
  </title>
  <meta name="generator" content="hexo-theme-ayer">
  
  <link rel="shortcut icon" href="https://dxysun.com/static/yan.png" />
  
  
<link rel="stylesheet" href="/dist/main.css">

  
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/Shen-Yu/cdn/css/remixicon.min.css">

  
<link rel="stylesheet" href="/css/custom.css">

  
  
<script src="https://cdn.jsdelivr.net/npm/pace-js@1.0.2/pace.min.js"></script>

  
  

  
<script>
var _hmt = _hmt || [];
(function() {
	var hm = document.createElement("script");
	hm.src = "https://hm.baidu.com/hm.js?aa994a8d65700b8835787dd39d079d7e";
	var s = document.getElementsByTagName("script")[0]; 
	s.parentNode.insertBefore(hm, s);
})();
</script>


</head>

</html>

<body>
  <div id="app">
    
      
    <main class="content on">
      <section class="outer">
  <article
  id="post-springForBean1"
  class="article article-type-post"
  itemscope
  itemprop="blogPost"
  data-scroll-reveal
>
  <div class="article-inner">
    
    <header class="article-header">
       
<h1 class="article-title sea-center" style="border-left:0" itemprop="name">
  spring核心之依赖注入
</h1>
 

    </header>
     
    <div class="article-meta">
      <a href="/2021/09/02/springForBean1/" class="article-date">
  <time datetime="2021-09-02T13:53:36.000Z" itemprop="datePublished">2021-09-02</time>
</a> 
  <div class="article-category">
    <a class="article-category-link" href="/categories/spring/">spring</a>
  </div>
  
<div class="word_count">
    <span class="post-time">
        <span class="post-meta-item-icon">
            <i class="ri-quill-pen-line"></i>
            <span class="post-meta-item-text"> 字数统计:</span>
            <span class="post-count">11.5k</span>
        </span>
    </span>

    <span class="post-time">
        &nbsp; | &nbsp;
        <span class="post-meta-item-icon">
            <i class="ri-book-open-line"></i>
            <span class="post-meta-item-text"> 阅读时长≈</span>
            <span class="post-count">52 分钟</span>
        </span>
    </span>
</div>
 
    </div>
      
    <div class="tocbot"></div>




  
    <div class="article-entry" itemprop="articleBody">
       
  <p>spring核心之依赖注入</p>
<a id="more"></a>

<h1 id="Spring自动装配之依赖注入"><a href="#Spring自动装配之依赖注入" class="headerlink" title="Spring自动装配之依赖注入"></a>Spring自动装配之依赖注入</h1><p>依赖注入发生的时间</p>
<p>当Spring IoC容器完成了Bean定义资源的定位、载入和解析注册以后，IOC容器中已经管理类Bean定义的相关数据，但是此时IoC容器还没有对所管理的Bean进行依赖注入，依赖注入在以下两种情况发生：</p>
<p>1）当用户在配置文件中<code>&lt;bean&gt;</code>元素未配置<code>lazy-init</code> 属性或者未使用 <code>@Lazy</code>(默认value为true)注解时，IOC容器会在解析注册Bean定义时进行预实例化，触发依赖注入。</p>
<p>2）当用户在配置文件中将<code>&lt;bean&gt;</code>元素配置了<code>lazy-init=false</code>属性或者使用<code>@Lazy</code>注解的value为false，IOC容器在解析注册Bean定义时进行预实例化，触发依赖注入。</p>
<p>IOC容器初始化时，会在方法<code>org.springframework.context.support.AbstractApplicationContext#finishBeanFactoryInitialization</code>中进行预实例化，触发依赖注入。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//对未配置lazy-init属性，或者lazy-init的值为false的Bean进行预实例化处理</span></span><br><span class="line"><span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">finishBeanFactoryInitialization</span><span class="params">(ConfigurableListableBeanFactory beanFactory)</span> </span>&#123;</span><br><span class="line">	<span class="comment">// Initialize conversion service for this context.</span></span><br><span class="line">	<span class="comment">//这是Spring3以后新加的代码，为容器指定一个转换服务(ConversionService)</span></span><br><span class="line">	<span class="comment">//在对某些Bean属性进行转换时使用</span></span><br><span class="line">	<span class="keyword">if</span> (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &amp;&amp;</span><br><span class="line">			beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService<span class="class">.<span class="keyword">class</span>)) </span>&#123;</span><br><span class="line">		beanFactory.setConversionService(</span><br><span class="line">				beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService<span class="class">.<span class="keyword">class</span>))</span>;</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="comment">// Register a default embedded value resolver if no bean post-processor</span></span><br><span class="line">	<span class="comment">// (such as a PropertyPlaceholderConfigurer bean) registered any before:</span></span><br><span class="line">	<span class="comment">// at this point, primarily for resolution in annotation attribute values.</span></span><br><span class="line">	<span class="keyword">if</span> (!beanFactory.hasEmbeddedValueResolver()) &#123;</span><br><span class="line">		beanFactory.addEmbeddedValueResolver(strVal -&gt; getEnvironment().resolvePlaceholders(strVal));</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="comment">// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.</span></span><br><span class="line">	String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware<span class="class">.<span class="keyword">class</span>, <span class="title">false</span>, <span class="title">false</span>)</span>;</span><br><span class="line">	<span class="keyword">for</span> (String weaverAwareName : weaverAwareNames) &#123;</span><br><span class="line">		getBean(weaverAwareName);</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="comment">// Stop using the temporary ClassLoader for type matching.</span></span><br><span class="line">	<span class="comment">//为了类型匹配，停止使用临时的类加载器</span></span><br><span class="line">	beanFactory.setTempClassLoader(<span class="keyword">null</span>);</span><br><span class="line"></span><br><span class="line">	<span class="comment">// Allow for caching all bean definition metadata, not expecting further changes.</span></span><br><span class="line">	<span class="comment">//缓存容器中所有注册的BeanDefinition元数据，以防被修改</span></span><br><span class="line">	beanFactory.freezeConfiguration();</span><br><span class="line"></span><br><span class="line">	<span class="comment">// Instantiate all remaining (non-lazy-init) singletons.</span></span><br><span class="line">	<span class="comment">//对配置了lazy-init属性的单态模式Bean进行预实例化处理</span></span><br><span class="line">	beanFactory.preInstantiateSingletons();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>beanFactory.preInstantiateSingletons()</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//对配置lazy-init属性单态Bean的预实例化</span></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">preInstantiateSingletons</span><span class="params">()</span> <span class="keyword">throws</span> BeansException </span>&#123;</span><br><span class="line">	<span class="keyword">if</span> (<span class="keyword">this</span>.logger.isDebugEnabled()) &#123;</span><br><span class="line">		<span class="keyword">this</span>.logger.debug(<span class="string">"Pre-instantiating singletons in "</span> + <span class="keyword">this</span>);</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="comment">// Iterate over a copy to allow for init methods which in turn register new bean definitions.</span></span><br><span class="line">	<span class="comment">// While this may not be part of the regular factory bootstrap, it does otherwise work fine.</span></span><br><span class="line">	List&lt;String&gt; beanNames = <span class="keyword">new</span> ArrayList&lt;&gt;(<span class="keyword">this</span>.beanDefinitionNames);</span><br><span class="line"></span><br><span class="line">	<span class="comment">// Trigger initialization of all non-lazy singleton beans...</span></span><br><span class="line">	<span class="keyword">for</span> (String beanName : beanNames) &#123;</span><br><span class="line">		<span class="comment">//获取指定名称的Bean定义</span></span><br><span class="line">		RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);</span><br><span class="line">		<span class="comment">//Bean不是抽象的，是单态模式的，且lazy-init属性配置为false，未配置懒加载属性是 bd.isLazyInit() 值为false</span></span><br><span class="line">		<span class="keyword">if</span> (!bd.isAbstract() &amp;&amp; bd.isSingleton() &amp;&amp; !bd.isLazyInit()) &#123;</span><br><span class="line">			<span class="comment">//如果指定名称的bean是创建容器的Bean</span></span><br><span class="line">			<span class="keyword">if</span> (isFactoryBean(beanName)) &#123;</span><br><span class="line">				<span class="comment">//FACTORY_BEAN_PREFIX=”&amp;”，当Bean名称前面加”&amp;”符号</span></span><br><span class="line">				<span class="comment">//时，获取的是产生容器对象本身，而不是容器产生的Bean.</span></span><br><span class="line">				<span class="comment">//调用getBean方法，触发容器对Bean实例化和依赖注入过程</span></span><br><span class="line">				<span class="keyword">final</span> FactoryBean&lt;?&gt; factory = (FactoryBean&lt;?&gt;) getBean(FACTORY_BEAN_PREFIX + beanName);</span><br><span class="line">				<span class="comment">//标识是否需要预实例化</span></span><br><span class="line">				<span class="keyword">boolean</span> isEagerInit;</span><br><span class="line">				<span class="keyword">if</span> (System.getSecurityManager() != <span class="keyword">null</span> &amp;&amp; factory <span class="keyword">instanceof</span> SmartFactoryBean) &#123;</span><br><span class="line">					<span class="comment">//一个匿名内部类</span></span><br><span class="line">					isEagerInit = AccessController.doPrivileged((PrivilegedAction&lt;Boolean&gt;) () -&gt;</span><br><span class="line">							((SmartFactoryBean&lt;?&gt;) factory).isEagerInit(),</span><br><span class="line">							getAccessControlContext());</span><br><span class="line">				&#125;</span><br><span class="line">				<span class="keyword">else</span> &#123;</span><br><span class="line">					isEagerInit = (factory <span class="keyword">instanceof</span> SmartFactoryBean &amp;&amp;</span><br><span class="line">							((SmartFactoryBean&lt;?&gt;) factory).isEagerInit());</span><br><span class="line">				&#125;</span><br><span class="line">				<span class="keyword">if</span> (isEagerInit) &#123;</span><br><span class="line">					<span class="comment">//调用getBean方法，触发容器对Bean实例化和依赖注入过程</span></span><br><span class="line">					getBean(beanName);</span><br><span class="line">				&#125;</span><br><span class="line">			&#125;</span><br><span class="line">			<span class="keyword">else</span> &#123;</span><br><span class="line">				getBean(beanName);</span><br><span class="line">			&#125;</span><br><span class="line">		&#125;</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="comment">// Trigger post-initialization callback for all applicable beans...</span></span><br><span class="line">	<span class="keyword">for</span> (String beanName : beanNames) &#123;</span><br><span class="line">		Object singletonInstance = getSingleton(beanName);</span><br><span class="line">		<span class="keyword">if</span> (singletonInstance <span class="keyword">instanceof</span> SmartInitializingSingleton) &#123;</span><br><span class="line">			<span class="keyword">final</span> SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;</span><br><span class="line">			<span class="keyword">if</span> (System.getSecurityManager() != <span class="keyword">null</span>) &#123;</span><br><span class="line">				AccessController.doPrivileged((PrivilegedAction&lt;Object&gt;) () -&gt; &#123;</span><br><span class="line">					smartSingleton.afterSingletonsInstantiated();</span><br><span class="line">					<span class="keyword">return</span> <span class="keyword">null</span>;</span><br><span class="line">				&#125;, getAccessControlContext());</span><br><span class="line">			&#125;</span><br><span class="line">			<span class="keyword">else</span> &#123;</span><br><span class="line">				smartSingleton.afterSingletonsInstantiated();</span><br><span class="line">			&#125;</span><br><span class="line">		&#125;</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<p>BeanFactory接口定义了Spring IoC容器的基本功能规范，是SpringIoC容器所应遵守的最底层和最基本的编程规范。</p>
<p>BeanFactory接口中定义了几个<code>getBean()</code>方法，就是用户向loC容器索取管理的Bean的方法，通过分析其子类的具体实现，理解SpringloC容器如何在<code>getBean()</code>完成依赖注入。</p>
<h2 id="getBean-的入口"><a href="#getBean-的入口" class="headerlink" title="getBean()的入口"></a><code>getBean()</code>的入口</h2><p>AbstractBeanFactory的<code>getBean()</code>相关方法的源码如下：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br><span class="line">221</span><br><span class="line">222</span><br><span class="line">223</span><br><span class="line">224</span><br><span class="line">225</span><br><span class="line">226</span><br><span class="line">227</span><br><span class="line">228</span><br><span class="line">229</span><br><span class="line">230</span><br><span class="line">231</span><br><span class="line">232</span><br><span class="line">233</span><br><span class="line">234</span><br><span class="line">235</span><br><span class="line">236</span><br><span class="line">237</span><br><span class="line">238</span><br><span class="line">239</span><br><span class="line">240</span><br><span class="line">241</span><br><span class="line">242</span><br><span class="line">243</span><br><span class="line">244</span><br><span class="line">245</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//获取IOC容器中指定名称的Bean</span></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> Object <span class="title">getBean</span><span class="params">(String name)</span> <span class="keyword">throws</span> BeansException </span>&#123;</span><br><span class="line">	<span class="comment">//doGetBean才是真正向IoC容器获取被管理Bean的过程</span></span><br><span class="line">	<span class="keyword">return</span> doGetBean(name, <span class="keyword">null</span>, <span class="keyword">null</span>, <span class="keyword">false</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//获取IOC容器中指定名称和类型的Bean</span></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="keyword">public</span> &lt;T&gt; <span class="function">T <span class="title">getBean</span><span class="params">(String name, @Nullable Class&lt;T&gt; requiredType)</span> <span class="keyword">throws</span> BeansException </span>&#123;</span><br><span class="line">	<span class="comment">//doGetBean才是真正向IoC容器获取被管理Bean的过程</span></span><br><span class="line">	<span class="keyword">return</span> doGetBean(name, requiredType, <span class="keyword">null</span>, <span class="keyword">false</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//获取IOC容器中指定名称和参数的Bean</span></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> Object <span class="title">getBean</span><span class="params">(String name, Object... args)</span> <span class="keyword">throws</span> BeansException </span>&#123;</span><br><span class="line">	<span class="comment">//doGetBean才是真正向IoC容器获取被管理Bean的过程</span></span><br><span class="line">	<span class="keyword">return</span> doGetBean(name, <span class="keyword">null</span>, args, <span class="keyword">false</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Return an instance, which may be shared or independent, of the specified bean.</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> name the name of the bean to retrieve</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> requiredType the required type of the bean to retrieve</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> args arguments to use when creating a bean instance using explicit arguments</span></span><br><span class="line"><span class="comment"> * (only applied when creating a new instance as opposed to retrieving an existing one)</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@return</span> an instance of the bean</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@throws</span> BeansException if the bean could not be created</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="comment">//获取IOC容器中指定名称、类型和参数的Bean</span></span><br><span class="line"><span class="keyword">public</span> &lt;T&gt; <span class="function">T <span class="title">getBean</span><span class="params">(String name, @Nullable Class&lt;T&gt; requiredType, @Nullable Object... args)</span></span></span><br><span class="line"><span class="function">		<span class="keyword">throws</span> BeansException </span>&#123;</span><br><span class="line">	<span class="comment">//doGetBean才是真正向IoC容器获取被管理Bean的过程</span></span><br><span class="line">	<span class="keyword">return</span> doGetBean(name, requiredType, args, <span class="keyword">false</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Return an instance, which may be shared or independent, of the specified bean.</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> name the name of the bean to retrieve</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> requiredType the required type of the bean to retrieve</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> args arguments to use when creating a bean instance using explicit arguments</span></span><br><span class="line"><span class="comment"> * (only applied when creating a new instance as opposed to retrieving an existing one)</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> typeCheckOnly whether the instance is obtained for a type check,</span></span><br><span class="line"><span class="comment"> * not for actual use</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@return</span> an instance of the bean</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@throws</span> BeansException if the bean could not be created</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="meta">@SuppressWarnings</span>(<span class="string">"unchecked"</span>)</span><br><span class="line"><span class="comment">//真正实现向IOC容器获取Bean的功能，也是触发依赖注入功能的地方</span></span><br><span class="line"><span class="keyword">protected</span> &lt;T&gt; <span class="function">T <span class="title">doGetBean</span><span class="params">(<span class="keyword">final</span> String name, @Nullable <span class="keyword">final</span> Class&lt;T&gt; requiredType,</span></span></span><br><span class="line"><span class="function"><span class="params">		@Nullable <span class="keyword">final</span> Object[] args, <span class="keyword">boolean</span> typeCheckOnly)</span> <span class="keyword">throws</span> BeansException </span>&#123;</span><br><span class="line"></span><br><span class="line">	<span class="comment">//根据指定的名称获取被管理Bean的名称，剥离指定名称中对容器的相关依赖</span></span><br><span class="line">	<span class="comment">//如果指定的是别名，将别名转换为规范的Bean名称</span></span><br><span class="line">	<span class="keyword">final</span> String beanName = transformedBeanName(name);</span><br><span class="line">	Object bean;</span><br><span class="line"></span><br><span class="line">	<span class="comment">// Eagerly check singleton cache for manually registered singletons.</span></span><br><span class="line">	<span class="comment">//先从缓存中取是否已经有被创建过的单态类型的Bean</span></span><br><span class="line">	<span class="comment">//对于单例模式的Bean整个IOC容器中只创建一次，不需要重复创建</span></span><br><span class="line">	Object sharedInstance = getSingleton(beanName);</span><br><span class="line">	<span class="comment">//IOC容器创建单例模式Bean实例对象</span></span><br><span class="line">	<span class="keyword">if</span> (sharedInstance != <span class="keyword">null</span> &amp;&amp; args == <span class="keyword">null</span>) &#123;</span><br><span class="line">		<span class="keyword">if</span> (logger.isDebugEnabled()) &#123;</span><br><span class="line">			<span class="comment">//如果指定名称的Bean在容器中已有单例模式的Bean被创建</span></span><br><span class="line">			<span class="comment">//直接返回已经创建的Bean</span></span><br><span class="line">			<span class="keyword">if</span> (isSingletonCurrentlyInCreation(beanName)) &#123;</span><br><span class="line">				logger.debug(<span class="string">"Returning eagerly cached instance of singleton bean '"</span> + beanName +</span><br><span class="line">						<span class="string">"' that is not fully initialized yet - a consequence of a circular reference"</span>);</span><br><span class="line">			&#125;</span><br><span class="line">			<span class="keyword">else</span> &#123;</span><br><span class="line">				logger.debug(<span class="string">"Returning cached instance of singleton bean '"</span> + beanName + <span class="string">"'"</span>);</span><br><span class="line">			&#125;</span><br><span class="line">		&#125;</span><br><span class="line">		<span class="comment">//获取给定Bean的实例对象，主要是完成FactoryBean的相关处理</span></span><br><span class="line">		<span class="comment">//注意：BeanFactory是管理容器中Bean的工厂，而FactoryBean是</span></span><br><span class="line">		<span class="comment">//创建创建对象的工厂Bean，两者之间有区别</span></span><br><span class="line">		bean = getObjectForBeanInstance(sharedInstance, name, beanName, <span class="keyword">null</span>);</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="keyword">else</span> &#123;</span><br><span class="line">		<span class="comment">// Fail if we're already creating this bean instance:</span></span><br><span class="line">		<span class="comment">// We're assumably within a circular reference.</span></span><br><span class="line">		<span class="comment">//缓存没有正在创建的单例模式Bean</span></span><br><span class="line">		<span class="comment">//缓存中已经有已经创建的原型模式Bean</span></span><br><span class="line">		<span class="comment">//但是由于循环引用的问题导致实例化对象失败</span></span><br><span class="line">		<span class="keyword">if</span> (isPrototypeCurrentlyInCreation(beanName)) &#123;</span><br><span class="line">			<span class="keyword">throw</span> <span class="keyword">new</span> BeanCurrentlyInCreationException(beanName);</span><br><span class="line">		&#125;</span><br><span class="line"></span><br><span class="line">		<span class="comment">// Check if bean definition exists in this factory.</span></span><br><span class="line">		<span class="comment">//对IOC容器中是否存在指定名称的BeanDefinition进行检查，首先检查是否</span></span><br><span class="line">		<span class="comment">//能在当前的BeanFactory中获取的所需要的Bean，如果不能则委托当前容器</span></span><br><span class="line">		<span class="comment">//的父级容器去查找，如果还是找不到则沿着容器的继承体系向父级容器查找</span></span><br><span class="line">		BeanFactory parentBeanFactory = getParentBeanFactory();</span><br><span class="line">		<span class="comment">//当前容器的父级容器存在，且当前容器中不存在指定名称的Bean</span></span><br><span class="line">		<span class="keyword">if</span> (parentBeanFactory != <span class="keyword">null</span> &amp;&amp; !containsBeanDefinition(beanName)) &#123;</span><br><span class="line">			<span class="comment">// Not found -&gt; check parent.</span></span><br><span class="line">			<span class="comment">//解析指定Bean名称的原始名称</span></span><br><span class="line">			String nameToLookup = originalBeanName(name);</span><br><span class="line">			<span class="keyword">if</span> (parentBeanFactory <span class="keyword">instanceof</span> AbstractBeanFactory) &#123;</span><br><span class="line">				<span class="keyword">return</span> ((AbstractBeanFactory) parentBeanFactory).doGetBean(</span><br><span class="line">						nameToLookup, requiredType, args, typeCheckOnly);</span><br><span class="line">			&#125;</span><br><span class="line">			<span class="keyword">else</span> <span class="keyword">if</span> (args != <span class="keyword">null</span>) &#123;</span><br><span class="line">				<span class="comment">// Delegation to parent with explicit args.</span></span><br><span class="line">				<span class="comment">//委派父级容器根据指定名称和显式的参数查找</span></span><br><span class="line">				<span class="keyword">return</span> (T) parentBeanFactory.getBean(nameToLookup, args);</span><br><span class="line">			&#125;</span><br><span class="line">			<span class="keyword">else</span> &#123;</span><br><span class="line">				<span class="comment">// No args -&gt; delegate to standard getBean method.</span></span><br><span class="line">				<span class="comment">//委派父级容器根据指定名称和类型查找</span></span><br><span class="line">				<span class="keyword">return</span> parentBeanFactory.getBean(nameToLookup, requiredType);</span><br><span class="line">			&#125;</span><br><span class="line">		&#125;</span><br><span class="line"></span><br><span class="line">		<span class="comment">//创建的Bean是否需要进行类型验证，一般不需要</span></span><br><span class="line">		<span class="keyword">if</span> (!typeCheckOnly) &#123;</span><br><span class="line">			<span class="comment">//向容器标记指定的Bean已经被创建</span></span><br><span class="line">			markBeanAsCreated(beanName);</span><br><span class="line">		&#125;</span><br><span class="line"></span><br><span class="line">		<span class="keyword">try</span> &#123;</span><br><span class="line">			<span class="comment">//根据指定Bean名称获取其父级的Bean定义</span></span><br><span class="line">			<span class="comment">//主要解决Bean继承时子类合并父类公共属性问题</span></span><br><span class="line">			<span class="keyword">final</span> RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);</span><br><span class="line">			checkMergedBeanDefinition(mbd, beanName, args);</span><br><span class="line"></span><br><span class="line">			<span class="comment">// Guarantee initialization of beans that the current bean depends on.</span></span><br><span class="line">			<span class="comment">//获取当前Bean所有依赖Bean的名称</span></span><br><span class="line">			String[] dependsOn = mbd.getDependsOn();</span><br><span class="line">			<span class="comment">//如果当前Bean有依赖Bean</span></span><br><span class="line">			<span class="keyword">if</span> (dependsOn != <span class="keyword">null</span>) &#123;</span><br><span class="line">				<span class="keyword">for</span> (String dep : dependsOn) &#123;</span><br><span class="line">					<span class="keyword">if</span> (isDependent(beanName, dep)) &#123;</span><br><span class="line">						<span class="keyword">throw</span> <span class="keyword">new</span> BeanCreationException(mbd.getResourceDescription(), beanName,</span><br><span class="line">								<span class="string">"Circular depends-on relationship between '"</span> + beanName + <span class="string">"' and '"</span> + dep + <span class="string">"'"</span>);</span><br><span class="line">					&#125;</span><br><span class="line">					<span class="comment">//递归调用getBean方法，获取当前Bean的依赖Bean</span></span><br><span class="line">					registerDependentBean(dep, beanName);</span><br><span class="line">					<span class="comment">//把被依赖Bean注册给当前依赖的Bean</span></span><br><span class="line">					getBean(dep);</span><br><span class="line">				&#125;</span><br><span class="line">			&#125;</span><br><span class="line"></span><br><span class="line">			<span class="comment">// Create bean instance.</span></span><br><span class="line">			<span class="comment">//创建单例模式Bean的实例对象</span></span><br><span class="line">			<span class="keyword">if</span> (mbd.isSingleton()) &#123;</span><br><span class="line">				<span class="comment">//这里使用了一个匿名内部类，创建Bean实例对象，并且注册给所依赖的对象</span></span><br><span class="line">				sharedInstance = getSingleton(beanName, () -&gt; &#123;</span><br><span class="line">					<span class="keyword">try</span> &#123;</span><br><span class="line">						<span class="comment">//创建一个指定Bean实例对象，如果有父级继承，则合并子类和父类的定义</span></span><br><span class="line">						<span class="keyword">return</span> createBean(beanName, mbd, args);</span><br><span class="line">					&#125;</span><br><span class="line">					<span class="keyword">catch</span> (BeansException ex) &#123;</span><br><span class="line">						<span class="comment">// Explicitly remove instance from singleton cache: It might have been put there</span></span><br><span class="line">						<span class="comment">// eagerly by the creation process, to allow for circular reference resolution.</span></span><br><span class="line">						<span class="comment">// Also remove any beans that received a temporary reference to the bean.</span></span><br><span class="line">						<span class="comment">//显式地从容器单例模式Bean缓存中清除实例对象</span></span><br><span class="line">						destroySingleton(beanName);</span><br><span class="line">						<span class="keyword">throw</span> ex;</span><br><span class="line">					&#125;</span><br><span class="line">				&#125;);</span><br><span class="line">				<span class="comment">//获取给定Bean的实例对象</span></span><br><span class="line">				bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);</span><br><span class="line">			&#125;</span><br><span class="line"></span><br><span class="line">			<span class="comment">//IOC容器创建原型模式Bean实例对象</span></span><br><span class="line">			<span class="keyword">else</span> <span class="keyword">if</span> (mbd.isPrototype()) &#123;</span><br><span class="line">				<span class="comment">// It's a prototype -&gt; create a new instance.</span></span><br><span class="line">				<span class="comment">//原型模式(Prototype)是每次都会创建一个新的对象</span></span><br><span class="line">				Object prototypeInstance = <span class="keyword">null</span>;</span><br><span class="line">				<span class="keyword">try</span> &#123;</span><br><span class="line">					<span class="comment">//回调beforePrototypeCreation方法，默认的功能是注册当前创建的原型对象</span></span><br><span class="line">					beforePrototypeCreation(beanName);</span><br><span class="line">					<span class="comment">//创建指定Bean对象实例</span></span><br><span class="line">					prototypeInstance = createBean(beanName, mbd, args);</span><br><span class="line">				&#125;</span><br><span class="line">				<span class="keyword">finally</span> &#123;</span><br><span class="line">					<span class="comment">//回调afterPrototypeCreation方法，默认的功能告诉IOC容器指定Bean的原型对象不再创建</span></span><br><span class="line">					afterPrototypeCreation(beanName);</span><br><span class="line">				&#125;</span><br><span class="line">				<span class="comment">//获取给定Bean的实例对象</span></span><br><span class="line">				bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);</span><br><span class="line">			&#125;</span><br><span class="line"></span><br><span class="line">			<span class="comment">//要创建的Bean既不是单例模式，也不是原型模式，则根据Bean定义资源中</span></span><br><span class="line">			<span class="comment">//配置的生命周期范围，选择实例化Bean的合适方法，这种在Web应用程序中</span></span><br><span class="line">			<span class="comment">//比较常用，如：request、session、application等生命周期</span></span><br><span class="line">			<span class="keyword">else</span> &#123;</span><br><span class="line">				String scopeName = mbd.getScope();</span><br><span class="line">				<span class="keyword">final</span> Scope scope = <span class="keyword">this</span>.scopes.get(scopeName);</span><br><span class="line">				<span class="comment">//Bean定义资源中没有配置生命周期范围，则Bean定义不合法</span></span><br><span class="line">				<span class="keyword">if</span> (scope == <span class="keyword">null</span>) &#123;</span><br><span class="line">					<span class="keyword">throw</span> <span class="keyword">new</span> IllegalStateException(<span class="string">"No Scope registered for scope name '"</span> + scopeName + <span class="string">"'"</span>);</span><br><span class="line">				&#125;</span><br><span class="line">				<span class="keyword">try</span> &#123;</span><br><span class="line">					<span class="comment">//这里又使用了一个匿名内部类，获取一个指定生命周期范围的实例</span></span><br><span class="line">					Object scopedInstance = scope.get(beanName, () -&gt; &#123;</span><br><span class="line">						beforePrototypeCreation(beanName);</span><br><span class="line">						<span class="keyword">try</span> &#123;</span><br><span class="line">							<span class="keyword">return</span> createBean(beanName, mbd, args);</span><br><span class="line">						&#125;</span><br><span class="line">						<span class="keyword">finally</span> &#123;</span><br><span class="line">							afterPrototypeCreation(beanName);</span><br><span class="line">						&#125;</span><br><span class="line">					&#125;);</span><br><span class="line">					<span class="comment">//获取给定Bean的实例对象</span></span><br><span class="line">					bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);</span><br><span class="line">				&#125;</span><br><span class="line">				<span class="keyword">catch</span> (IllegalStateException ex) &#123;</span><br><span class="line">					<span class="keyword">throw</span> <span class="keyword">new</span> BeanCreationException(beanName,</span><br><span class="line">							<span class="string">"Scope '"</span> + scopeName + <span class="string">"' is not active for the current thread; consider "</span> +</span><br><span class="line">							<span class="string">"defining a scoped proxy for this bean if you intend to refer to it from a singleton"</span>,</span><br><span class="line">							ex);</span><br><span class="line">				&#125;</span><br><span class="line">			&#125;</span><br><span class="line">		&#125;</span><br><span class="line">		<span class="keyword">catch</span> (BeansException ex) &#123;</span><br><span class="line">			cleanupAfterBeanCreationFailure(beanName);</span><br><span class="line">			<span class="keyword">throw</span> ex;</span><br><span class="line">		&#125;</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="comment">// Check if required type matches the type of the actual bean instance.</span></span><br><span class="line">	<span class="comment">//对创建的Bean实例对象进行类型检查</span></span><br><span class="line">	<span class="keyword">if</span> (requiredType != <span class="keyword">null</span> &amp;&amp; !requiredType.isInstance(bean)) &#123;</span><br><span class="line">		<span class="keyword">try</span> &#123;</span><br><span class="line">			T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);</span><br><span class="line">			<span class="keyword">if</span> (convertedBean == <span class="keyword">null</span>) &#123;</span><br><span class="line">				<span class="keyword">throw</span> <span class="keyword">new</span> BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());</span><br><span class="line">			&#125;</span><br><span class="line">			<span class="keyword">return</span> convertedBean;</span><br><span class="line">		&#125;</span><br><span class="line">		<span class="keyword">catch</span> (TypeMismatchException ex) &#123;</span><br><span class="line">			<span class="keyword">if</span> (logger.isDebugEnabled()) &#123;</span><br><span class="line">				logger.debug(<span class="string">"Failed to convert bean '"</span> + name + <span class="string">"' to required type '"</span> +</span><br><span class="line">						ClassUtils.getQualifiedName(requiredType) + <span class="string">"'"</span>, ex);</span><br><span class="line">			&#125;</span><br><span class="line">			<span class="keyword">throw</span> <span class="keyword">new</span> BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());</span><br><span class="line">		&#125;</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="keyword">return</span> (T) bean;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>通过上面对向IoC容器获取Bean方法的分析，可以看到在Spring中，如果Bean定义的单例模式（Singleton），则容器在创建之前先从缓存中查找，以确保整个容器中只存在一个实例对象。</p>
<p>如果Bean定义的是原型模式（Prototype），则容器每次都会创建一个新的实例对象。除此之外，Bean定义还可以扩展为指定其生命周期范围。</p>
<p>上面的源码只是定义了根据Bean定义的模式采取的不同创建Bean实例对象的策略具体的Bean精实例对象的创建过程由实现了ObjectFactory接口的匿名内部类的<code>createBean()</code>方法完成，ObjectFactory使用委派模式，具体的Bean实例创建过程交由其实现类 AbstractAutowireCapableBeanFactory完成，继续分析AbstractAutowireCapableBeanFactory 的<code>createBean()</code>方法的源码，理解其创建Bean实例的具体实现过程。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//创建Bean实例对象</span></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">protected</span> Object <span class="title">createBean</span><span class="params">(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)</span></span></span><br><span class="line"><span class="function">		<span class="keyword">throws</span> BeanCreationException </span>&#123;</span><br><span class="line"></span><br><span class="line">	<span class="keyword">if</span> (logger.isDebugEnabled()) &#123;</span><br><span class="line">		logger.debug(<span class="string">"Creating instance of bean '"</span> + beanName + <span class="string">"'"</span>);</span><br><span class="line">	&#125;</span><br><span class="line">	RootBeanDefinition mbdToUse = mbd;</span><br><span class="line"></span><br><span class="line">	<span class="comment">// Make sure bean class is actually resolved at this point, and</span></span><br><span class="line">	<span class="comment">// clone the bean definition in case of a dynamically resolved Class</span></span><br><span class="line">	<span class="comment">// which cannot be stored in the shared merged bean definition.</span></span><br><span class="line">	<span class="comment">//判断需要创建的Bean是否可以实例化，即是否可以通过当前的类加载器加载</span></span><br><span class="line">	Class&lt;?&gt; resolvedClass = resolveBeanClass(mbd, beanName);</span><br><span class="line">	<span class="keyword">if</span> (resolvedClass != <span class="keyword">null</span> &amp;&amp; !mbd.hasBeanClass() &amp;&amp; mbd.getBeanClassName() != <span class="keyword">null</span>) &#123;</span><br><span class="line">		mbdToUse = <span class="keyword">new</span> RootBeanDefinition(mbd);</span><br><span class="line">		mbdToUse.setBeanClass(resolvedClass);</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="comment">// Prepare method overrides.</span></span><br><span class="line">	<span class="comment">//校验和准备Bean中的方法覆盖</span></span><br><span class="line">	<span class="keyword">try</span> &#123;</span><br><span class="line">		mbdToUse.prepareMethodOverrides();</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="keyword">catch</span> (BeanDefinitionValidationException ex) &#123;</span><br><span class="line">		<span class="keyword">throw</span> <span class="keyword">new</span> BeanDefinitionStoreException(mbdToUse.getResourceDescription(),</span><br><span class="line">				beanName, <span class="string">"Validation of method overrides failed"</span>, ex);</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="keyword">try</span> &#123;</span><br><span class="line">		<span class="comment">// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.</span></span><br><span class="line">		<span class="comment">//如果Bean配置了初始化前和初始化后的处理器，则试图返回一个需要创建Bean的代理对象</span></span><br><span class="line">		Object bean = resolveBeforeInstantiation(beanName, mbdToUse);</span><br><span class="line">		<span class="keyword">if</span> (bean != <span class="keyword">null</span>) &#123;</span><br><span class="line">			<span class="keyword">return</span> bean;</span><br><span class="line">		&#125;</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="keyword">catch</span> (Throwable ex) &#123;</span><br><span class="line">		<span class="keyword">throw</span> <span class="keyword">new</span> BeanCreationException(mbdToUse.getResourceDescription(), beanName,</span><br><span class="line">				<span class="string">"BeanPostProcessor before instantiation of bean failed"</span>, ex);</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="keyword">try</span> &#123;</span><br><span class="line">		<span class="comment">//创建Bean的入口</span></span><br><span class="line">		Object beanInstance = doCreateBean(beanName, mbdToUse, args);</span><br><span class="line">		<span class="keyword">if</span> (logger.isDebugEnabled()) &#123;</span><br><span class="line">			logger.debug(<span class="string">"Finished creating instance of bean '"</span> + beanName + <span class="string">"'"</span>);</span><br><span class="line">		&#125;</span><br><span class="line">		<span class="keyword">return</span> beanInstance;</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="keyword">catch</span> (BeanCreationException ex) &#123;</span><br><span class="line">		<span class="comment">// A previously detected exception with proper bean creation context already...</span></span><br><span class="line">		<span class="keyword">throw</span> ex;</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="keyword">catch</span> (ImplicitlyAppearedSingletonException ex) &#123;</span><br><span class="line">		<span class="comment">// An IllegalStateException to be communicated up to DefaultSingletonBeanRegistry...</span></span><br><span class="line">		<span class="keyword">throw</span> ex;</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="keyword">catch</span> (Throwable ex) &#123;</span><br><span class="line">		<span class="keyword">throw</span> <span class="keyword">new</span> BeanCreationException(</span><br><span class="line">				mbdToUse.getResourceDescription(), beanName, <span class="string">"Unexpected exception during bean creation"</span>, ex);</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Actually create the specified bean. Pre-creation processing has already happened</span></span><br><span class="line"><span class="comment"> * at this point, e.g. checking &#123;<span class="doctag">@code</span> postProcessBeforeInstantiation&#125; callbacks.</span></span><br><span class="line"><span class="comment"> * &lt;p&gt;Differentiates between default bean instantiation, use of a</span></span><br><span class="line"><span class="comment"> * factory method, and autowiring a constructor.</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> beanName the name of the bean</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> mbd the merged bean definition for the bean</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> args explicit arguments to use for constructor or factory method invocation</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@return</span> a new instance of the bean</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@throws</span> BeanCreationException if the bean could not be created</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@see</span> #instantiateBean</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@see</span> #instantiateUsingFactoryMethod</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@see</span> #autowireConstructor</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="comment">//真正创建Bean的方法</span></span><br><span class="line"><span class="function"><span class="keyword">protected</span> Object <span class="title">doCreateBean</span><span class="params">(<span class="keyword">final</span> String beanName, <span class="keyword">final</span> RootBeanDefinition mbd, <span class="keyword">final</span> @Nullable Object[] args)</span></span></span><br><span class="line"><span class="function">		<span class="keyword">throws</span> BeanCreationException </span>&#123;</span><br><span class="line"></span><br><span class="line">	<span class="comment">// Instantiate the bean.</span></span><br><span class="line">	<span class="comment">//封装被创建的Bean对象</span></span><br><span class="line">	BeanWrapper instanceWrapper = <span class="keyword">null</span>;</span><br><span class="line">	<span class="keyword">if</span> (mbd.isSingleton()) &#123;</span><br><span class="line">		instanceWrapper = <span class="keyword">this</span>.factoryBeanInstanceCache.remove(beanName);</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="keyword">if</span> (instanceWrapper == <span class="keyword">null</span>) &#123;</span><br><span class="line">		instanceWrapper = createBeanInstance(beanName, mbd, args);</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="keyword">final</span> Object bean = instanceWrapper.getWrappedInstance();</span><br><span class="line">	<span class="comment">//获取实例化对象的类型</span></span><br><span class="line">	Class&lt;?&gt; beanType = instanceWrapper.getWrappedClass();</span><br><span class="line">	<span class="keyword">if</span> (beanType != NullBean<span class="class">.<span class="keyword">class</span>) </span>&#123;</span><br><span class="line">		mbd.resolvedTargetType = beanType;</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="comment">// Allow post-processors to modify the merged bean definition.</span></span><br><span class="line">	<span class="comment">//调用PostProcessor后置处理器</span></span><br><span class="line">	<span class="keyword">synchronized</span> (mbd.postProcessingLock) &#123;</span><br><span class="line">		<span class="keyword">if</span> (!mbd.postProcessed) &#123;</span><br><span class="line">			<span class="keyword">try</span> &#123;</span><br><span class="line">				applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);</span><br><span class="line">			&#125;</span><br><span class="line">			<span class="keyword">catch</span> (Throwable ex) &#123;</span><br><span class="line">				<span class="keyword">throw</span> <span class="keyword">new</span> BeanCreationException(mbd.getResourceDescription(), beanName,</span><br><span class="line">						<span class="string">"Post-processing of merged bean definition failed"</span>, ex);</span><br><span class="line">			&#125;</span><br><span class="line">			mbd.postProcessed = <span class="keyword">true</span>;</span><br><span class="line">		&#125;</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="comment">// Eagerly cache singletons to be able to resolve circular references</span></span><br><span class="line">	<span class="comment">// even when triggered by lifecycle interfaces like BeanFactoryAware.</span></span><br><span class="line">	<span class="comment">//向容器中缓存单例模式的Bean对象，以防循环引用</span></span><br><span class="line">	<span class="keyword">boolean</span> earlySingletonExposure = (mbd.isSingleton() &amp;&amp; <span class="keyword">this</span>.allowCircularReferences &amp;&amp;</span><br><span class="line">			isSingletonCurrentlyInCreation(beanName));</span><br><span class="line">	<span class="keyword">if</span> (earlySingletonExposure) &#123;</span><br><span class="line">		<span class="keyword">if</span> (logger.isDebugEnabled()) &#123;</span><br><span class="line">			logger.debug(<span class="string">"Eagerly caching bean '"</span> + beanName +</span><br><span class="line">					<span class="string">"' to allow for resolving potential circular references"</span>);</span><br><span class="line">		&#125;</span><br><span class="line">		<span class="comment">//这里是一个匿名内部类，为了防止循环引用，尽早持有对象的引用</span></span><br><span class="line">		addSingletonFactory(beanName, () -&gt; getEarlyBeanReference(beanName, mbd, bean));</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="comment">// Initialize the bean instance.</span></span><br><span class="line">	<span class="comment">//Bean对象的初始化，依赖注入在此触发</span></span><br><span class="line">	<span class="comment">//这个exposedObject在初始化完成之后返回作为依赖注入完成后的Bean</span></span><br><span class="line">	Object exposedObject = bean;</span><br><span class="line">	<span class="keyword">try</span> &#123;</span><br><span class="line">		<span class="comment">//将Bean实例对象封装，并且Bean定义中配置的属性值赋值给实例对象</span></span><br><span class="line">		populateBean(beanName, mbd, instanceWrapper);</span><br><span class="line">		<span class="comment">//初始化Bean对象</span></span><br><span class="line">		exposedObject = initializeBean(beanName, exposedObject, mbd);</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="keyword">catch</span> (Throwable ex) &#123;</span><br><span class="line">		<span class="keyword">if</span> (ex <span class="keyword">instanceof</span> BeanCreationException &amp;&amp; beanName.equals(((BeanCreationException) ex).getBeanName())) &#123;</span><br><span class="line">			<span class="keyword">throw</span> (BeanCreationException) ex;</span><br><span class="line">		&#125;</span><br><span class="line">		<span class="keyword">else</span> &#123;</span><br><span class="line">			<span class="keyword">throw</span> <span class="keyword">new</span> BeanCreationException(</span><br><span class="line">					mbd.getResourceDescription(), beanName, <span class="string">"Initialization of bean failed"</span>, ex);</span><br><span class="line">		&#125;</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="keyword">if</span> (earlySingletonExposure) &#123;</span><br><span class="line">		<span class="comment">//获取指定名称的已注册的单例模式Bean对象</span></span><br><span class="line">		Object earlySingletonReference = getSingleton(beanName, <span class="keyword">false</span>);</span><br><span class="line">		<span class="keyword">if</span> (earlySingletonReference != <span class="keyword">null</span>) &#123;</span><br><span class="line">			<span class="comment">//根据名称获取的已注册的Bean和正在实例化的Bean是同一个</span></span><br><span class="line">			<span class="keyword">if</span> (exposedObject == bean) &#123;</span><br><span class="line">				<span class="comment">//当前实例化的Bean初始化完成</span></span><br><span class="line">				exposedObject = earlySingletonReference;</span><br><span class="line">			&#125;</span><br><span class="line">			<span class="comment">//当前Bean依赖其他Bean，并且当发生循环引用时不允许新创建实例对象</span></span><br><span class="line">			<span class="keyword">else</span> <span class="keyword">if</span> (!<span class="keyword">this</span>.allowRawInjectionDespiteWrapping &amp;&amp; hasDependentBean(beanName)) &#123;</span><br><span class="line">				String[] dependentBeans = getDependentBeans(beanName);</span><br><span class="line">				Set&lt;String&gt; actualDependentBeans = <span class="keyword">new</span> LinkedHashSet&lt;&gt;(dependentBeans.length);</span><br><span class="line">				<span class="comment">//获取当前Bean所依赖的其他Bean</span></span><br><span class="line">				<span class="keyword">for</span> (String dependentBean : dependentBeans) &#123;</span><br><span class="line">					<span class="comment">//对依赖Bean进行类型检查</span></span><br><span class="line">					<span class="keyword">if</span> (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) &#123;</span><br><span class="line">						actualDependentBeans.add(dependentBean);</span><br><span class="line">					&#125;</span><br><span class="line">				&#125;</span><br><span class="line">				<span class="keyword">if</span> (!actualDependentBeans.isEmpty()) &#123;</span><br><span class="line">					<span class="keyword">throw</span> <span class="keyword">new</span> BeanCurrentlyInCreationException(beanName,</span><br><span class="line">							<span class="string">"Bean with name '"</span> + beanName + <span class="string">"' has been injected into other beans ["</span> +</span><br><span class="line">							StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +</span><br><span class="line">							<span class="string">"] in its raw version as part of a circular reference, but has eventually been "</span> +</span><br><span class="line">							<span class="string">"wrapped. This means that said other beans do not use the final version of the "</span> +</span><br><span class="line">							<span class="string">"bean. This is often the result of over-eager type matching - consider using "</span> +</span><br><span class="line">							<span class="string">"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example."</span>);</span><br><span class="line">				&#125;</span><br><span class="line">			&#125;</span><br><span class="line">		&#125;</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="comment">// Register bean as disposable.</span></span><br><span class="line">	<span class="comment">//注册完成依赖注入的Bean</span></span><br><span class="line">	<span class="keyword">try</span> &#123;</span><br><span class="line">		registerDisposableBeanIfNecessary(beanName, bean, mbd);</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="keyword">catch</span> (BeanDefinitionValidationException ex) &#123;</span><br><span class="line">		<span class="keyword">throw</span> <span class="keyword">new</span> BeanCreationException(</span><br><span class="line">				mbd.getResourceDescription(), beanName, <span class="string">"Invalid destruction signature"</span>, ex);</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="keyword">return</span> exposedObject;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<p>通过上面的源码注释，看到具体的依赖注入实现其实就在以下两个方法中：</p>
<p>1）<code>createBeanlnstance()</code>方法，生成Bean所包含的java对象实例。</p>
<p>2）<code>populateBean()</code>方法，对Bean属性的依赖注入进行处理。</p>
<p>下面继续分析这两个方法的代码实现</p>
<h3 id="选择Bean实例化策略"><a href="#选择Bean实例化策略" class="headerlink" title="选择Bean实例化策略"></a>选择Bean实例化策略</h3><p>在 <code>createBeanInstance()</code>方法中，根据指定的初始化策略，使用简单工厂方法或者容器的自动装配特性生成Java实例对象,创建对象的源码如下：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//创建Bean的实例对象</span></span><br><span class="line"><span class="function"><span class="keyword">protected</span> BeanWrapper <span class="title">createBeanInstance</span><span class="params">(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)</span> </span>&#123;</span><br><span class="line">	<span class="comment">// Make sure bean class is actually resolved at this point.</span></span><br><span class="line">	<span class="comment">//检查确认Bean是可实例化的</span></span><br><span class="line">	Class&lt;?&gt; beanClass = resolveBeanClass(mbd, beanName);</span><br><span class="line"></span><br><span class="line">	<span class="comment">//使用工厂方法对Bean进行实例化</span></span><br><span class="line">	<span class="keyword">if</span> (beanClass != <span class="keyword">null</span> &amp;&amp; !Modifier.isPublic(beanClass.getModifiers()) &amp;&amp; !mbd.isNonPublicAccessAllowed()) &#123;</span><br><span class="line">		<span class="keyword">throw</span> <span class="keyword">new</span> BeanCreationException(mbd.getResourceDescription(), beanName,</span><br><span class="line">				<span class="string">"Bean class isn't public, and non-public access not allowed: "</span> + beanClass.getName());</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	Supplier&lt;?&gt; instanceSupplier = mbd.getInstanceSupplier();</span><br><span class="line">	<span class="keyword">if</span> (instanceSupplier != <span class="keyword">null</span>) &#123;</span><br><span class="line">		<span class="keyword">return</span> obtainFromSupplier(instanceSupplier, beanName);</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="keyword">if</span> (mbd.getFactoryMethodName() != <span class="keyword">null</span>)  &#123;</span><br><span class="line">		<span class="comment">//调用工厂方法实例化</span></span><br><span class="line">		<span class="keyword">return</span> instantiateUsingFactoryMethod(beanName, mbd, args);</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="comment">// Shortcut when re-creating the same bean...</span></span><br><span class="line">	<span class="comment">//使用容器的自动装配方法进行实例化</span></span><br><span class="line">	<span class="keyword">boolean</span> resolved = <span class="keyword">false</span>;</span><br><span class="line">	<span class="keyword">boolean</span> autowireNecessary = <span class="keyword">false</span>;</span><br><span class="line">	<span class="keyword">if</span> (args == <span class="keyword">null</span>) &#123;</span><br><span class="line">		<span class="keyword">synchronized</span> (mbd.constructorArgumentLock) &#123;</span><br><span class="line">			<span class="keyword">if</span> (mbd.resolvedConstructorOrFactoryMethod != <span class="keyword">null</span>) &#123;</span><br><span class="line">				resolved = <span class="keyword">true</span>;</span><br><span class="line">				autowireNecessary = mbd.constructorArgumentsResolved;</span><br><span class="line">			&#125;</span><br><span class="line">		&#125;</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="keyword">if</span> (resolved) &#123;</span><br><span class="line">		<span class="keyword">if</span> (autowireNecessary) &#123;</span><br><span class="line">			<span class="comment">//配置了自动装配属性，使用容器的自动装配实例化</span></span><br><span class="line">			<span class="comment">//容器的自动装配是根据参数类型匹配Bean的构造方法</span></span><br><span class="line">			<span class="keyword">return</span> autowireConstructor(beanName, mbd, <span class="keyword">null</span>, <span class="keyword">null</span>);</span><br><span class="line">		&#125;</span><br><span class="line">		<span class="keyword">else</span> &#123;</span><br><span class="line">			<span class="comment">//使用默认的无参构造方法实例化</span></span><br><span class="line">			<span class="keyword">return</span> instantiateBean(beanName, mbd);</span><br><span class="line">		&#125;</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="comment">// Need to determine the constructor...</span></span><br><span class="line">	<span class="comment">//使用Bean的构造方法进行实例化</span></span><br><span class="line">	Constructor&lt;?&gt;[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);</span><br><span class="line">	<span class="keyword">if</span> (ctors != <span class="keyword">null</span> ||</span><br><span class="line">			mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||</span><br><span class="line">			mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))  &#123;</span><br><span class="line">		<span class="comment">//使用容器的自动装配特性，调用匹配的构造方法实例化</span></span><br><span class="line">		<span class="keyword">return</span> autowireConstructor(beanName, mbd, ctors, args);</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="comment">// No special handling: simply use no-arg constructor.</span></span><br><span class="line">	<span class="comment">//使用默认的无参构造方法实例化</span></span><br><span class="line">	<span class="keyword">return</span> instantiateBean(beanName, mbd);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>经过对上面的代码分析，可以看出，对使用工厂方法和自动装配特性的Bean的实例化相当比较清楚，调用相应的工厂方法或者参数匹配的构造方法即可完成实例化对象的工作，但是对于我们最常使用的默认无参构造方法就需要使用相应的初始化策略（JDK的反射机制或者CGLib）来进行初始化了</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//使用默认的无参构造方法实例化Bean对象</span></span><br><span class="line">	<span class="function"><span class="keyword">protected</span> BeanWrapper <span class="title">instantiateBean</span><span class="params">(<span class="keyword">final</span> String beanName, <span class="keyword">final</span> RootBeanDefinition mbd)</span> </span>&#123;</span><br><span class="line">		<span class="keyword">try</span> &#123;</span><br><span class="line">			Object beanInstance;</span><br><span class="line">			<span class="keyword">final</span> BeanFactory parent = <span class="keyword">this</span>;</span><br><span class="line">			<span class="comment">//获取系统的安全管理接口，JDK标准的安全管理API</span></span><br><span class="line">			<span class="keyword">if</span> (System.getSecurityManager() != <span class="keyword">null</span>) &#123;</span><br><span class="line">				<span class="comment">//这里是一个匿名内置类，根据实例化策略创建实例对象</span></span><br><span class="line">				beanInstance = AccessController.doPrivileged((PrivilegedAction&lt;Object&gt;) () -&gt;</span><br><span class="line">						getInstantiationStrategy().instantiate(mbd, beanName, parent),</span><br><span class="line">						getAccessControlContext());</span><br><span class="line">			&#125;</span><br><span class="line">			<span class="keyword">else</span> &#123;</span><br><span class="line">				<span class="comment">//将实例化的对象封装起来</span></span><br><span class="line">				beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);</span><br><span class="line">			&#125;</span><br><span class="line">			BeanWrapper bw = <span class="keyword">new</span> BeanWrapperImpl(beanInstance);</span><br><span class="line">			initBeanWrapper(bw);</span><br><span class="line">			<span class="keyword">return</span> bw;</span><br><span class="line">		&#125;</span><br><span class="line">		<span class="keyword">catch</span> (Throwable ex) &#123;</span><br><span class="line">			<span class="keyword">throw</span> <span class="keyword">new</span> BeanCreationException(</span><br><span class="line">					mbd.getResourceDescription(), beanName, <span class="string">"Instantiation of bean failed"</span>, ex);</span><br><span class="line">		&#125;</span><br><span class="line">	&#125;</span><br></pre></td></tr></table></figure>

<p>在方法<code>getlnstantiationStrategy().instantiate()</code>中就具体实现类使用初始策略实例化对象。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//使用初始化策略实例化Bean对象</span></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> Object <span class="title">instantiate</span><span class="params">(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner)</span> </span>&#123;</span><br><span class="line">	<span class="comment">// Don't override the class with CGLIB if no overrides.</span></span><br><span class="line">	<span class="comment">//如果Bean定义中没有方法覆盖，则就不需要CGLIB父类类的方法</span></span><br><span class="line">	<span class="keyword">if</span> (!bd.hasMethodOverrides()) &#123;</span><br><span class="line">		Constructor&lt;?&gt; constructorToUse;</span><br><span class="line">		<span class="keyword">synchronized</span> (bd.constructorArgumentLock) &#123;</span><br><span class="line">			<span class="comment">//获取对象的构造方法或工厂方法</span></span><br><span class="line">			constructorToUse = (Constructor&lt;?&gt;) bd.resolvedConstructorOrFactoryMethod;</span><br><span class="line">			<span class="comment">//如果没有构造方法且没有工厂方法</span></span><br><span class="line">			<span class="keyword">if</span> (constructorToUse == <span class="keyword">null</span>) &#123;</span><br><span class="line">				<span class="comment">//使用JDK的反射机制，判断要实例化的Bean是否是接口</span></span><br><span class="line">				<span class="keyword">final</span> Class&lt;?&gt; clazz = bd.getBeanClass();</span><br><span class="line">				<span class="keyword">if</span> (clazz.isInterface()) &#123;</span><br><span class="line">					<span class="keyword">throw</span> <span class="keyword">new</span> BeanInstantiationException(clazz, <span class="string">"Specified class is an interface"</span>);</span><br><span class="line">				&#125;</span><br><span class="line">				<span class="keyword">try</span> &#123;</span><br><span class="line">					<span class="keyword">if</span> (System.getSecurityManager() != <span class="keyword">null</span>) &#123;</span><br><span class="line">						<span class="comment">//这里是一个匿名内置类，使用反射机制获取Bean的构造方法</span></span><br><span class="line">						constructorToUse = AccessController.doPrivileged(</span><br><span class="line">								(PrivilegedExceptionAction&lt;Constructor&lt;?&gt;&gt;) () -&gt; clazz.getDeclaredConstructor());</span><br><span class="line">					&#125;</span><br><span class="line">					<span class="keyword">else</span> &#123;</span><br><span class="line">						constructorToUse =	clazz.getDeclaredConstructor();</span><br><span class="line">					&#125;</span><br><span class="line">					bd.resolvedConstructorOrFactoryMethod = constructorToUse;</span><br><span class="line">				&#125;</span><br><span class="line">				<span class="keyword">catch</span> (Throwable ex) &#123;</span><br><span class="line">					<span class="keyword">throw</span> <span class="keyword">new</span> BeanInstantiationException(clazz, <span class="string">"No default constructor found"</span>, ex);</span><br><span class="line">				&#125;</span><br><span class="line">			&#125;</span><br><span class="line">		&#125;</span><br><span class="line">		<span class="comment">//使用BeanUtils实例化，通过反射机制调用”构造方法.newInstance(arg)”来进行实例化</span></span><br><span class="line">		<span class="keyword">return</span> BeanUtils.instantiateClass(constructorToUse);</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="keyword">else</span> &#123;</span><br><span class="line">		<span class="comment">// Must generate CGLIB subclass.</span></span><br><span class="line">		<span class="comment">//使用CGLIB来实例化对象</span></span><br><span class="line">		<span class="keyword">return</span> instantiateWithMethodInjection(bd, beanName, owner);</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>通过上面的代码分析，我们看到了如果Bean没有方法被覆盖了，则使用JDK的反射机制进行实例化，否则，使用CGLib进行实例化。</p>
<p><code>instantiateWithMethodlnjection()</code>方法调用SimplelnstantiationStrategy的子类CGLibSubclassinglnstantiationStrategy使用CGLib来进行初始化，其源码如下：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//使用CGLIB进行Bean对象实例化</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> Object <span class="title">instantiate</span><span class="params">(@Nullable Constructor&lt;?&gt; ctor, @Nullable Object... args)</span> </span>&#123;</span><br><span class="line">	<span class="comment">//创建代理子类</span></span><br><span class="line">	Class&lt;?&gt; subclass = createEnhancedSubclass(<span class="keyword">this</span>.beanDefinition);</span><br><span class="line">	Object instance;</span><br><span class="line">	<span class="keyword">if</span> (ctor == <span class="keyword">null</span>) &#123;</span><br><span class="line">		instance = BeanUtils.instantiateClass(subclass);</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="keyword">else</span> &#123;</span><br><span class="line">		<span class="keyword">try</span> &#123;</span><br><span class="line">			Constructor&lt;?&gt; enhancedSubclassConstructor = subclass.getConstructor(ctor.getParameterTypes());</span><br><span class="line">			instance = enhancedSubclassConstructor.newInstance(args);</span><br><span class="line">		&#125;</span><br><span class="line">		<span class="keyword">catch</span> (Exception ex) &#123;</span><br><span class="line">			<span class="keyword">throw</span> <span class="keyword">new</span> BeanInstantiationException(<span class="keyword">this</span>.beanDefinition.getBeanClass(),</span><br><span class="line">					<span class="string">"Failed to invoke constructor for CGLIB enhanced subclass ["</span> + subclass.getName() + <span class="string">"]"</span>, ex);</span><br><span class="line">		&#125;</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="comment">// SPR-10785: set callbacks directly on the instance instead of in the</span></span><br><span class="line">	<span class="comment">// enhanced class (via the Enhancer) in order to avoid memory leaks.</span></span><br><span class="line">	Factory factory = (Factory) instance;</span><br><span class="line">	factory.setCallbacks(<span class="keyword">new</span> Callback[] &#123;NoOp.INSTANCE,</span><br><span class="line">			<span class="keyword">new</span> LookupOverrideMethodInterceptor(<span class="keyword">this</span>.beanDefinition, <span class="keyword">this</span>.owner),</span><br><span class="line">			<span class="keyword">new</span> ReplaceOverrideMethodInterceptor(<span class="keyword">this</span>.beanDefinition, <span class="keyword">this</span>.owner)&#125;);</span><br><span class="line">	<span class="keyword">return</span> instance;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>CGLib是一个常用的字节码生成器的类库，它提供了一系列API实现Java字节码的生成和转换功能。</p>
<p>JDK的动态代理只能针对接口，如果一个类没有实现任何接口，要对其进行动态代理只能使用CGLib。</p>
<h3 id="准备依赖注入"><a href="#准备依赖注入" class="headerlink" title="准备依赖注入"></a>准备依赖注入</h3><p>在前面的分析中已经了解到Bean的依赖注入主要分为两个步骤，首先调用<code>createBeanInstance()</code>方法生成Bean所包含的Java对象实例。然后，调用<code>populateBean()</code>方法，对Bean属性的依赖注入进行处理。</p>
<p>上面我们已经分析了容器初始化生成Bean所包含的Java实例对象的过程，现在我们继续分析生成对象后，Spring IoC容器是如何将Bean的属性依赖关系注入Bean实例对象中并设置好的，回到<code>AbstractAutowireCapableBeanFactory的populateBean()</code>方法，对属性依赖注入的代码如下：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//将Bean属性设置到生成的实例对象上</span></span><br><span class="line"><span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">populateBean</span><span class="params">(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw)</span> </span>&#123;</span><br><span class="line">	<span class="keyword">if</span> (bw == <span class="keyword">null</span>) &#123;</span><br><span class="line">		<span class="keyword">if</span> (mbd.hasPropertyValues()) &#123;</span><br><span class="line">			<span class="keyword">throw</span> <span class="keyword">new</span> BeanCreationException(</span><br><span class="line">					mbd.getResourceDescription(), beanName, <span class="string">"Cannot apply property values to null instance"</span>);</span><br><span class="line">		&#125;</span><br><span class="line">		<span class="keyword">else</span> &#123;</span><br><span class="line">			<span class="comment">// Skip property population phase for null instance.</span></span><br><span class="line">			<span class="keyword">return</span>;</span><br><span class="line">		&#125;</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="comment">// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the</span></span><br><span class="line">	<span class="comment">// state of the bean before properties are set. This can be used, for example,</span></span><br><span class="line">	<span class="comment">// to support styles of field injection.</span></span><br><span class="line">	<span class="keyword">boolean</span> continueWithPropertyPopulation = <span class="keyword">true</span>;</span><br><span class="line"></span><br><span class="line">	<span class="keyword">if</span> (!mbd.isSynthetic() &amp;&amp; hasInstantiationAwareBeanPostProcessors()) &#123;</span><br><span class="line">		<span class="keyword">for</span> (BeanPostProcessor bp : getBeanPostProcessors()) &#123;</span><br><span class="line">			<span class="keyword">if</span> (bp <span class="keyword">instanceof</span> InstantiationAwareBeanPostProcessor) &#123;</span><br><span class="line">				InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;</span><br><span class="line">				<span class="keyword">if</span> (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) &#123;</span><br><span class="line">					continueWithPropertyPopulation = <span class="keyword">false</span>;</span><br><span class="line">					<span class="keyword">break</span>;</span><br><span class="line">				&#125;</span><br><span class="line">			&#125;</span><br><span class="line">		&#125;</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="keyword">if</span> (!continueWithPropertyPopulation) &#123;</span><br><span class="line">		<span class="keyword">return</span>;</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="comment">//获取容器在解析Bean定义资源时为BeanDefiniton中设置的属性值</span></span><br><span class="line">	PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : <span class="keyword">null</span>);</span><br><span class="line"></span><br><span class="line">	<span class="comment">//对依赖注入处理，首先处理autowiring自动装配的依赖注入</span></span><br><span class="line">	<span class="keyword">if</span> (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||</span><br><span class="line">			mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) &#123;</span><br><span class="line">		MutablePropertyValues newPvs = <span class="keyword">new</span> MutablePropertyValues(pvs);</span><br><span class="line"></span><br><span class="line">		<span class="comment">// Add property values based on autowire by name if applicable.</span></span><br><span class="line">		<span class="comment">//根据Bean名称进行autowiring自动装配处理</span></span><br><span class="line">		<span class="keyword">if</span> (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) &#123;</span><br><span class="line">			autowireByName(beanName, mbd, bw, newPvs);</span><br><span class="line">		&#125;</span><br><span class="line"></span><br><span class="line">		<span class="comment">// Add property values based on autowire by type if applicable.</span></span><br><span class="line">		<span class="comment">//根据Bean类型进行autowiring自动装配处理</span></span><br><span class="line">		<span class="keyword">if</span> (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) &#123;</span><br><span class="line">			autowireByType(beanName, mbd, bw, newPvs);</span><br><span class="line">		&#125;</span><br><span class="line"></span><br><span class="line">		pvs = newPvs;</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="comment">//对非autowiring的属性进行依赖注入处理</span></span><br><span class="line">	<span class="keyword">boolean</span> hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();</span><br><span class="line">	<span class="keyword">boolean</span> needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);</span><br><span class="line"></span><br><span class="line">	<span class="keyword">if</span> (hasInstAwareBpps || needsDepCheck) &#123;</span><br><span class="line">		<span class="keyword">if</span> (pvs == <span class="keyword">null</span>) &#123;</span><br><span class="line">			pvs = mbd.getPropertyValues();</span><br><span class="line">		&#125;</span><br><span class="line">		PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);</span><br><span class="line">		<span class="keyword">if</span> (hasInstAwareBpps) &#123;</span><br><span class="line">			<span class="keyword">for</span> (BeanPostProcessor bp : getBeanPostProcessors()) &#123;</span><br><span class="line">				<span class="keyword">if</span> (bp <span class="keyword">instanceof</span> InstantiationAwareBeanPostProcessor) &#123;</span><br><span class="line">					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;</span><br><span class="line">					pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);</span><br><span class="line">					<span class="keyword">if</span> (pvs == <span class="keyword">null</span>) &#123;</span><br><span class="line">						<span class="keyword">return</span>;</span><br><span class="line">					&#125;</span><br><span class="line">				&#125;</span><br><span class="line">			&#125;</span><br><span class="line">		&#125;</span><br><span class="line">		<span class="keyword">if</span> (needsDepCheck) &#123;</span><br><span class="line">			checkDependencies(beanName, mbd, filteredPds, pvs);</span><br><span class="line">		&#125;</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="keyword">if</span> (pvs != <span class="keyword">null</span>) &#123;</span><br><span class="line">		<span class="comment">//对属性进行注入</span></span><br><span class="line">		applyPropertyValues(beanName, mbd, bw, pvs);</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//解析并注入依赖属性的过程</span></span><br><span class="line"><span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">applyPropertyValues</span><span class="params">(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs)</span> </span>&#123;</span><br><span class="line">	<span class="keyword">if</span> (pvs.isEmpty()) &#123;</span><br><span class="line">		<span class="keyword">return</span>;</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="comment">//封装属性值</span></span><br><span class="line">	MutablePropertyValues mpvs = <span class="keyword">null</span>;</span><br><span class="line">	List&lt;PropertyValue&gt; original;</span><br><span class="line"></span><br><span class="line">	<span class="keyword">if</span> (System.getSecurityManager() != <span class="keyword">null</span>) &#123;</span><br><span class="line">		<span class="keyword">if</span> (bw <span class="keyword">instanceof</span> BeanWrapperImpl) &#123;</span><br><span class="line">			<span class="comment">//设置安全上下文，JDK安全机制</span></span><br><span class="line">			((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());</span><br><span class="line">		&#125;</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="keyword">if</span> (pvs <span class="keyword">instanceof</span> MutablePropertyValues) &#123;</span><br><span class="line">		mpvs = (MutablePropertyValues) pvs;</span><br><span class="line">		<span class="comment">//属性值已经转换</span></span><br><span class="line">		<span class="keyword">if</span> (mpvs.isConverted()) &#123;</span><br><span class="line">			<span class="comment">// Shortcut: use the pre-converted values as-is.</span></span><br><span class="line">			<span class="keyword">try</span> &#123;</span><br><span class="line">				<span class="comment">//为实例化对象设置属性值</span></span><br><span class="line">				bw.setPropertyValues(mpvs);</span><br><span class="line">				<span class="keyword">return</span>;</span><br><span class="line">			&#125;</span><br><span class="line">			<span class="keyword">catch</span> (BeansException ex) &#123;</span><br><span class="line">				<span class="keyword">throw</span> <span class="keyword">new</span> BeanCreationException(</span><br><span class="line">						mbd.getResourceDescription(), beanName, <span class="string">"Error setting property values"</span>, ex);</span><br><span class="line">			&#125;</span><br><span class="line">		&#125;</span><br><span class="line">		<span class="comment">//获取属性值对象的原始类型值</span></span><br><span class="line">		original = mpvs.getPropertyValueList();</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="keyword">else</span> &#123;</span><br><span class="line">		original = Arrays.asList(pvs.getPropertyValues());</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="comment">//获取用户自定义的类型转换</span></span><br><span class="line">	TypeConverter converter = getCustomTypeConverter();</span><br><span class="line">	<span class="keyword">if</span> (converter == <span class="keyword">null</span>) &#123;</span><br><span class="line">		converter = bw;</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="comment">//创建一个Bean定义属性值解析器，将Bean定义中的属性值解析为Bean实例对象的实际值</span></span><br><span class="line">	BeanDefinitionValueResolver valueResolver = <span class="keyword">new</span> BeanDefinitionValueResolver(<span class="keyword">this</span>, beanName, mbd, converter);</span><br><span class="line"></span><br><span class="line">	<span class="comment">// Create a deep copy, resolving any references for values.</span></span><br><span class="line"></span><br><span class="line">	<span class="comment">//为属性的解析值创建一个拷贝，将拷贝的数据注入到实例对象中</span></span><br><span class="line">	List&lt;PropertyValue&gt; deepCopy = <span class="keyword">new</span> ArrayList&lt;&gt;(original.size());</span><br><span class="line">	<span class="keyword">boolean</span> resolveNecessary = <span class="keyword">false</span>;</span><br><span class="line">	<span class="keyword">for</span> (PropertyValue pv : original) &#123;</span><br><span class="line">		<span class="comment">//属性值不需要转换</span></span><br><span class="line">		<span class="keyword">if</span> (pv.isConverted()) &#123;</span><br><span class="line">			deepCopy.add(pv);</span><br><span class="line">		&#125;</span><br><span class="line">		<span class="comment">//属性值需要转换</span></span><br><span class="line">		<span class="keyword">else</span> &#123;</span><br><span class="line">			String propertyName = pv.getName();</span><br><span class="line">			<span class="comment">//原始的属性值，即转换之前的属性值</span></span><br><span class="line">			Object originalValue = pv.getValue();</span><br><span class="line">			<span class="comment">//转换属性值，例如将引用转换为IOC容器中实例化对象引用</span></span><br><span class="line">			Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);</span><br><span class="line">			<span class="comment">//转换之后的属性值</span></span><br><span class="line">			Object convertedValue = resolvedValue;</span><br><span class="line">			<span class="comment">//属性值是否可以转换</span></span><br><span class="line">			<span class="keyword">boolean</span> convertible = bw.isWritableProperty(propertyName) &amp;&amp;</span><br><span class="line">					!PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);</span><br><span class="line">			<span class="keyword">if</span> (convertible) &#123;</span><br><span class="line">				<span class="comment">//使用用户自定义的类型转换器转换属性值</span></span><br><span class="line">				convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);</span><br><span class="line">			&#125;</span><br><span class="line">			<span class="comment">// Possibly store converted value in merged bean definition,</span></span><br><span class="line">			<span class="comment">// in order to avoid re-conversion for every created bean instance.</span></span><br><span class="line">			<span class="comment">//存储转换后的属性值，避免每次属性注入时的转换工作</span></span><br><span class="line">			<span class="keyword">if</span> (resolvedValue == originalValue) &#123;</span><br><span class="line">				<span class="keyword">if</span> (convertible) &#123;</span><br><span class="line">					<span class="comment">//设置属性转换之后的值</span></span><br><span class="line">					pv.setConvertedValue(convertedValue);</span><br><span class="line">				&#125;</span><br><span class="line">				deepCopy.add(pv);</span><br><span class="line">			&#125;</span><br><span class="line">			<span class="comment">//属性是可转换的，且属性原始值是字符串类型，且属性的原始类型值不是</span></span><br><span class="line">			<span class="comment">//动态生成的字符串，且属性的原始值不是集合或者数组类型</span></span><br><span class="line">			<span class="keyword">else</span> <span class="keyword">if</span> (convertible &amp;&amp; originalValue <span class="keyword">instanceof</span> TypedStringValue &amp;&amp;</span><br><span class="line">					!((TypedStringValue) originalValue).isDynamic() &amp;&amp;</span><br><span class="line">					!(convertedValue <span class="keyword">instanceof</span> Collection || ObjectUtils.isArray(convertedValue))) &#123;</span><br><span class="line">				pv.setConvertedValue(convertedValue);</span><br><span class="line">				<span class="comment">//重新封装属性的值</span></span><br><span class="line">				deepCopy.add(pv);</span><br><span class="line">			&#125;</span><br><span class="line">			<span class="keyword">else</span> &#123;</span><br><span class="line">				resolveNecessary = <span class="keyword">true</span>;</span><br><span class="line">				deepCopy.add(<span class="keyword">new</span> PropertyValue(pv, convertedValue));</span><br><span class="line">			&#125;</span><br><span class="line">		&#125;</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="keyword">if</span> (mpvs != <span class="keyword">null</span> &amp;&amp; !resolveNecessary) &#123;</span><br><span class="line">		<span class="comment">//标记属性值已经转换过</span></span><br><span class="line">		mpvs.setConverted();</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="comment">// Set our (possibly massaged) deep copy.</span></span><br><span class="line">	<span class="comment">//进行属性依赖注入</span></span><br><span class="line">	<span class="keyword">try</span> &#123;</span><br><span class="line">		bw.setPropertyValues(<span class="keyword">new</span> MutablePropertyValues(deepCopy));</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="keyword">catch</span> (BeansException ex) &#123;</span><br><span class="line">		<span class="keyword">throw</span> <span class="keyword">new</span> BeanCreationException(</span><br><span class="line">				mbd.getResourceDescription(), beanName, <span class="string">"Error setting property values"</span>, ex);</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>分析上述代码，我们可以看出，对属性的注入过程分以下两种情况：</p>
<p>1）属性值类型不需要强制转换时，不需要解析属性值，直接准备进行依赖注入。</p>
<p>2）属性值需要进行类型强制转换时，如对其他对象的引用等，首先需要解析属性值，然后对解析后的属性值进行依赖注入。</p>
<p>对属性值的解析是在BeanDefinitionValueResolver类中的<code>resolveValuelfNecessary()</code>方法中进行的，对属性值的依赖注入是通过<code>bw.setPropertyValues()</code>方法实现的，在分析属性值的依赖注入之前，我们先分析一下对属性值的解析过程。</p>
<h4 id="解析属性注入规则"><a href="#解析属性注入规则" class="headerlink" title="解析属性注入规则"></a>解析属性注入规则</h4><p>当容器在对属性进行依赖注入时，如果发现属性值需要进行类型转换，如属性值是容器中另一个Bean实例对象的引用，则容器首先需要根据属性值解析出所引用的对象，然后才能将该引用对象注入到目标实例对象的属性上去，对属性进行解析的<code>resolveValuelfNecessary()</code>方法实现，其源码如下：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//解析属性值，对注入类型进行转换</span></span><br><span class="line"><span class="meta">@Nullable</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> Object <span class="title">resolveValueIfNecessary</span><span class="params">(Object argName, @Nullable Object value)</span> </span>&#123;</span><br><span class="line">	<span class="comment">// We must check each value to see whether it requires a runtime reference</span></span><br><span class="line">	<span class="comment">// to another bean to be resolved.</span></span><br><span class="line">	<span class="comment">//对引用类型的属性进行解析</span></span><br><span class="line">	<span class="keyword">if</span> (value <span class="keyword">instanceof</span> RuntimeBeanReference) &#123;</span><br><span class="line">		RuntimeBeanReference ref = (RuntimeBeanReference) value;</span><br><span class="line">		<span class="comment">//调用引用类型属性的解析方法</span></span><br><span class="line">		<span class="keyword">return</span> resolveReference(argName, ref);</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="comment">//对属性值是引用容器中另一个Bean名称的解析</span></span><br><span class="line">	<span class="keyword">else</span> <span class="keyword">if</span> (value <span class="keyword">instanceof</span> RuntimeBeanNameReference) &#123;</span><br><span class="line">		String refName = ((RuntimeBeanNameReference) value).getBeanName();</span><br><span class="line">		refName = String.valueOf(doEvaluate(refName));</span><br><span class="line">		<span class="comment">//从容器中获取指定名称的Bean</span></span><br><span class="line">		<span class="keyword">if</span> (!<span class="keyword">this</span>.beanFactory.containsBean(refName)) &#123;</span><br><span class="line">			<span class="keyword">throw</span> <span class="keyword">new</span> BeanDefinitionStoreException(</span><br><span class="line">					<span class="string">"Invalid bean name '"</span> + refName + <span class="string">"' in bean reference for "</span> + argName);</span><br><span class="line">		&#125;</span><br><span class="line">		<span class="keyword">return</span> refName;</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="comment">//对Bean类型属性的解析，主要是Bean中的内部类</span></span><br><span class="line">	<span class="keyword">else</span> <span class="keyword">if</span> (value <span class="keyword">instanceof</span> BeanDefinitionHolder) &#123;</span><br><span class="line">		<span class="comment">// Resolve BeanDefinitionHolder: contains BeanDefinition with name and aliases.</span></span><br><span class="line">		BeanDefinitionHolder bdHolder = (BeanDefinitionHolder) value;</span><br><span class="line">		<span class="keyword">return</span> resolveInnerBean(argName, bdHolder.getBeanName(), bdHolder.getBeanDefinition());</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="keyword">else</span> <span class="keyword">if</span> (value <span class="keyword">instanceof</span> BeanDefinition) &#123;</span><br><span class="line">		<span class="comment">// Resolve plain BeanDefinition, without contained name: use dummy name.</span></span><br><span class="line">		BeanDefinition bd = (BeanDefinition) value;</span><br><span class="line">		String innerBeanName = <span class="string">"(inner bean)"</span> + BeanFactoryUtils.GENERATED_BEAN_NAME_SEPARATOR +</span><br><span class="line">				ObjectUtils.getIdentityHexString(bd);</span><br><span class="line">		<span class="keyword">return</span> resolveInnerBean(argName, innerBeanName, bd);</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="comment">//对集合数组类型的属性解析</span></span><br><span class="line">	<span class="keyword">else</span> <span class="keyword">if</span> (value <span class="keyword">instanceof</span> ManagedArray) &#123;</span><br><span class="line">		<span class="comment">// May need to resolve contained runtime references.</span></span><br><span class="line">		ManagedArray array = (ManagedArray) value;</span><br><span class="line">		<span class="comment">//获取数组的类型</span></span><br><span class="line">		Class&lt;?&gt; elementType = array.resolvedElementType;</span><br><span class="line">		<span class="keyword">if</span> (elementType == <span class="keyword">null</span>) &#123;</span><br><span class="line">			<span class="comment">//获取数组元素的类型</span></span><br><span class="line">			String elementTypeName = array.getElementTypeName();</span><br><span class="line">			<span class="keyword">if</span> (StringUtils.hasText(elementTypeName)) &#123;</span><br><span class="line">				<span class="keyword">try</span> &#123;</span><br><span class="line">					<span class="comment">//使用反射机制创建指定类型的对象</span></span><br><span class="line">					elementType = ClassUtils.forName(elementTypeName, <span class="keyword">this</span>.beanFactory.getBeanClassLoader());</span><br><span class="line">					array.resolvedElementType = elementType;</span><br><span class="line">				&#125;</span><br><span class="line">				<span class="keyword">catch</span> (Throwable ex) &#123;</span><br><span class="line">					<span class="comment">// Improve the message by showing the context.</span></span><br><span class="line">					<span class="keyword">throw</span> <span class="keyword">new</span> BeanCreationException(</span><br><span class="line">							<span class="keyword">this</span>.beanDefinition.getResourceDescription(), <span class="keyword">this</span>.beanName,</span><br><span class="line">							<span class="string">"Error resolving array type for "</span> + argName, ex);</span><br><span class="line">				&#125;</span><br><span class="line">			&#125;</span><br><span class="line">			<span class="comment">//没有获取到数组的类型，也没有获取到数组元素的类型</span></span><br><span class="line">			<span class="comment">//则直接设置数组的类型为Object</span></span><br><span class="line">			<span class="keyword">else</span> &#123;</span><br><span class="line">				elementType = Object<span class="class">.<span class="keyword">class</span></span>;</span><br><span class="line">			&#125;</span><br><span class="line">		&#125;</span><br><span class="line">		<span class="comment">//创建指定类型的数组</span></span><br><span class="line">		<span class="keyword">return</span> resolveManagedArray(argName, (List&lt;?&gt;) value, elementType);</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="comment">//解析list类型的属性值</span></span><br><span class="line">	<span class="keyword">else</span> <span class="keyword">if</span> (value <span class="keyword">instanceof</span> ManagedList) &#123;</span><br><span class="line">		<span class="comment">// May need to resolve contained runtime references.</span></span><br><span class="line">		<span class="keyword">return</span> resolveManagedList(argName, (List&lt;?&gt;) value);</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="comment">//解析set类型的属性值</span></span><br><span class="line">	<span class="keyword">else</span> <span class="keyword">if</span> (value <span class="keyword">instanceof</span> ManagedSet) &#123;</span><br><span class="line">		<span class="comment">// May need to resolve contained runtime references.</span></span><br><span class="line">		<span class="keyword">return</span> resolveManagedSet(argName, (Set&lt;?&gt;) value);</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="comment">//解析map类型的属性值</span></span><br><span class="line">	<span class="keyword">else</span> <span class="keyword">if</span> (value <span class="keyword">instanceof</span> ManagedMap) &#123;</span><br><span class="line">		<span class="comment">// May need to resolve contained runtime references.</span></span><br><span class="line">		<span class="keyword">return</span> resolveManagedMap(argName, (Map&lt;?, ?&gt;) value);</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="comment">//解析props类型的属性值，props其实就是key和value均为字符串的map</span></span><br><span class="line">	<span class="keyword">else</span> <span class="keyword">if</span> (value <span class="keyword">instanceof</span> ManagedProperties) &#123;</span><br><span class="line">		Properties original = (Properties) value;</span><br><span class="line">		<span class="comment">//创建一个拷贝，用于作为解析后的返回值</span></span><br><span class="line">		Properties copy = <span class="keyword">new</span> Properties();</span><br><span class="line">		original.forEach((propKey, propValue) -&gt; &#123;</span><br><span class="line">			<span class="keyword">if</span> (propKey <span class="keyword">instanceof</span> TypedStringValue) &#123;</span><br><span class="line">				propKey = evaluate((TypedStringValue) propKey);</span><br><span class="line">			&#125;</span><br><span class="line">			<span class="keyword">if</span> (propValue <span class="keyword">instanceof</span> TypedStringValue) &#123;</span><br><span class="line">				propValue = evaluate((TypedStringValue) propValue);</span><br><span class="line">			&#125;</span><br><span class="line">			<span class="keyword">if</span> (propKey == <span class="keyword">null</span> || propValue == <span class="keyword">null</span>) &#123;</span><br><span class="line">				<span class="keyword">throw</span> <span class="keyword">new</span> BeanCreationException(</span><br><span class="line">						<span class="keyword">this</span>.beanDefinition.getResourceDescription(), <span class="keyword">this</span>.beanName,</span><br><span class="line">						<span class="string">"Error converting Properties key/value pair for "</span> + argName + <span class="string">": resolved to null"</span>);</span><br><span class="line">			&#125;</span><br><span class="line">			copy.put(propKey, propValue);</span><br><span class="line">		&#125;);</span><br><span class="line">		<span class="keyword">return</span> copy;</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="comment">//解析字符串类型的属性值</span></span><br><span class="line">	<span class="keyword">else</span> <span class="keyword">if</span> (value <span class="keyword">instanceof</span> TypedStringValue) &#123;</span><br><span class="line">		<span class="comment">// Convert value to target type here.</span></span><br><span class="line">		TypedStringValue typedStringValue = (TypedStringValue) value;</span><br><span class="line">		Object valueObject = evaluate(typedStringValue);</span><br><span class="line">		<span class="keyword">try</span> &#123;</span><br><span class="line">			<span class="comment">//获取属性的目标类型</span></span><br><span class="line">			Class&lt;?&gt; resolvedTargetType = resolveTargetType(typedStringValue);</span><br><span class="line">			<span class="keyword">if</span> (resolvedTargetType != <span class="keyword">null</span>) &#123;</span><br><span class="line">				<span class="comment">//对目标类型的属性进行解析，递归调用</span></span><br><span class="line">				<span class="keyword">return</span> <span class="keyword">this</span>.typeConverter.convertIfNecessary(valueObject, resolvedTargetType);</span><br><span class="line">			&#125;</span><br><span class="line">			<span class="comment">//没有获取到属性的目标对象，则按Object类型返回</span></span><br><span class="line">			<span class="keyword">else</span> &#123;</span><br><span class="line">				<span class="keyword">return</span> valueObject;</span><br><span class="line">			&#125;</span><br><span class="line">		&#125;</span><br><span class="line">		<span class="keyword">catch</span> (Throwable ex) &#123;</span><br><span class="line">			<span class="comment">// Improve the message by showing the context.</span></span><br><span class="line">			<span class="keyword">throw</span> <span class="keyword">new</span> BeanCreationException(</span><br><span class="line">					<span class="keyword">this</span>.beanDefinition.getResourceDescription(), <span class="keyword">this</span>.beanName,</span><br><span class="line">					<span class="string">"Error converting typed String value for "</span> + argName, ex);</span><br><span class="line">		&#125;</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="keyword">else</span> <span class="keyword">if</span> (value <span class="keyword">instanceof</span> NullBean) &#123;</span><br><span class="line">		<span class="keyword">return</span> <span class="keyword">null</span>;</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="keyword">else</span> &#123;</span><br><span class="line">		<span class="keyword">return</span> evaluate(value);</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>通过上面的代码分析，我们明白了Spring是如何将引用类型，内部类以及集合类型等属性进行解析的，属性值解析完成后就可以进行依赖注入了，依赖注入的过程就是Bean对象实例设置到它所依赖的Bean对象属性上去。而真正的依赖注入是通过bw.setPropertyValues（）方法实现的，该方法也使用了委托模式，在BeanWrapper接口中至少定义了方法声明，依赖注入的具体实现交由其实现类BeanWrapperlmpl来完成，下面我们就分析依BeanWrapperlmpl中赖注入相关的源码。</p>
<h3 id="注入赋值"><a href="#注入赋值" class="headerlink" title="注入赋值"></a>注入赋值</h3><p>BeanWrapperlmpl类主要是对容器中完成初始化的Bean实例对象进行属性的依赖注入，即把Bean对象设置到它所依赖的另一个Bean的属性中去。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//进行属性依赖注入</span></span><br><span class="line">		<span class="keyword">try</span> &#123;</span><br><span class="line">			bw.setPropertyValues(<span class="keyword">new</span> MutablePropertyValues(deepCopy));</span><br><span class="line">		&#125;</span><br></pre></td></tr></table></figure>

<p>然而，BeanWrapperlmpl中的注入方法最终会走到AbstractNestablePropertyAccessor的setPropertyValue方法，其相关源码如下：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//实现属性依赖注入功能</span></span><br><span class="line"><span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">setPropertyValue</span><span class="params">(PropertyTokenHolder tokens, PropertyValue pv)</span> <span class="keyword">throws</span> BeansException </span>&#123;</span><br><span class="line">	<span class="keyword">if</span> (tokens.keys != <span class="keyword">null</span>) &#123;</span><br><span class="line">		processKeyedProperty(tokens, pv);</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="keyword">else</span> &#123;</span><br><span class="line">		processLocalProperty(tokens, pv);</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//实现属性依赖注入功能</span></span><br><span class="line"><span class="meta">@SuppressWarnings</span>(<span class="string">"unchecked"</span>)</span><br><span class="line"><span class="function"><span class="keyword">private</span> <span class="keyword">void</span> <span class="title">processKeyedProperty</span><span class="params">(PropertyTokenHolder tokens, PropertyValue pv)</span> </span>&#123;</span><br><span class="line">	<span class="comment">//调用属性的getter方法，获取属性的值</span></span><br><span class="line">	Object propValue = getPropertyHoldingValue(tokens);</span><br><span class="line">	PropertyHandler ph = getLocalPropertyHandler(tokens.actualName);</span><br><span class="line">	<span class="keyword">if</span> (ph == <span class="keyword">null</span>) &#123;</span><br><span class="line">		<span class="keyword">throw</span> <span class="keyword">new</span> InvalidPropertyException(</span><br><span class="line">				getRootClass(), <span class="keyword">this</span>.nestedPath + tokens.actualName, <span class="string">"No property handler found"</span>);</span><br><span class="line">	&#125;</span><br><span class="line">	Assert.state(tokens.keys != <span class="keyword">null</span>, <span class="string">"No token keys"</span>);</span><br><span class="line">	String lastKey = tokens.keys[tokens.keys.length - <span class="number">1</span>];</span><br><span class="line"></span><br><span class="line">	<span class="comment">//注入array类型的属性值</span></span><br><span class="line">	<span class="keyword">if</span> (propValue.getClass().isArray()) &#123;</span><br><span class="line">		Class&lt;?&gt; requiredType = propValue.getClass().getComponentType();</span><br><span class="line">		<span class="keyword">int</span> arrayIndex = Integer.parseInt(lastKey);</span><br><span class="line">		Object oldValue = <span class="keyword">null</span>;</span><br><span class="line">		<span class="keyword">try</span> &#123;</span><br><span class="line">			<span class="keyword">if</span> (isExtractOldValueForEditor() &amp;&amp; arrayIndex &lt; Array.getLength(propValue)) &#123;</span><br><span class="line">				oldValue = Array.get(propValue, arrayIndex);</span><br><span class="line">			&#125;</span><br><span class="line">			Object convertedValue = convertIfNecessary(tokens.canonicalName, oldValue, pv.getValue(),</span><br><span class="line">					requiredType, ph.nested(tokens.keys.length));</span><br><span class="line">			<span class="comment">//获取集合类型属性的长度</span></span><br><span class="line">			<span class="keyword">int</span> length = Array.getLength(propValue);</span><br><span class="line">			<span class="keyword">if</span> (arrayIndex &gt;= length &amp;&amp; arrayIndex &lt; <span class="keyword">this</span>.autoGrowCollectionLimit) &#123;</span><br><span class="line">				Class&lt;?&gt; componentType = propValue.getClass().getComponentType();</span><br><span class="line">				Object newArray = Array.newInstance(componentType, arrayIndex + <span class="number">1</span>);</span><br><span class="line">				System.arraycopy(propValue, <span class="number">0</span>, newArray, <span class="number">0</span>, length);</span><br><span class="line">				setPropertyValue(tokens.actualName, newArray);</span><br><span class="line">				<span class="comment">//调用属性的getter方法，获取属性的值</span></span><br><span class="line">				propValue = getPropertyValue(tokens.actualName);</span><br><span class="line">			&#125;</span><br><span class="line">			<span class="comment">//将属性的值赋值给数组中的元素</span></span><br><span class="line">			Array.set(propValue, arrayIndex, convertedValue);</span><br><span class="line">		&#125;</span><br><span class="line">		<span class="keyword">catch</span> (IndexOutOfBoundsException ex) &#123;</span><br><span class="line">			<span class="keyword">throw</span> <span class="keyword">new</span> InvalidPropertyException(getRootClass(), <span class="keyword">this</span>.nestedPath + tokens.canonicalName,</span><br><span class="line">					<span class="string">"Invalid array index in property path '"</span> + tokens.canonicalName + <span class="string">"'"</span>, ex);</span><br><span class="line">		&#125;</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="comment">//注入list类型的属性值</span></span><br><span class="line">	<span class="keyword">else</span> <span class="keyword">if</span> (propValue <span class="keyword">instanceof</span> List) &#123;</span><br><span class="line">		<span class="comment">//获取list集合的类型</span></span><br><span class="line">		Class&lt;?&gt; requiredType = ph.getCollectionType(tokens.keys.length);</span><br><span class="line">		List&lt;Object&gt; list = (List&lt;Object&gt;) propValue;</span><br><span class="line">		<span class="comment">//获取list集合的size</span></span><br><span class="line">		<span class="keyword">int</span> index = Integer.parseInt(lastKey);</span><br><span class="line">		Object oldValue = <span class="keyword">null</span>;</span><br><span class="line">		<span class="keyword">if</span> (isExtractOldValueForEditor() &amp;&amp; index &lt; list.size()) &#123;</span><br><span class="line">			oldValue = list.get(index);</span><br><span class="line">		&#125;</span><br><span class="line">		<span class="comment">//获取list解析后的属性值</span></span><br><span class="line">		Object convertedValue = convertIfNecessary(tokens.canonicalName, oldValue, pv.getValue(),</span><br><span class="line">				requiredType, ph.nested(tokens.keys.length));</span><br><span class="line">		<span class="keyword">int</span> size = list.size();</span><br><span class="line">		<span class="comment">//如果list的长度大于属性值的长度，则多余的元素赋值为null</span></span><br><span class="line">		<span class="keyword">if</span> (index &gt;= size &amp;&amp; index &lt; <span class="keyword">this</span>.autoGrowCollectionLimit) &#123;</span><br><span class="line">			<span class="keyword">for</span> (<span class="keyword">int</span> i = size; i &lt; index; i++) &#123;</span><br><span class="line">				<span class="keyword">try</span> &#123;</span><br><span class="line">					list.add(<span class="keyword">null</span>);</span><br><span class="line">				&#125;</span><br><span class="line">				<span class="keyword">catch</span> (NullPointerException ex) &#123;</span><br><span class="line">					<span class="keyword">throw</span> <span class="keyword">new</span> InvalidPropertyException(getRootClass(), <span class="keyword">this</span>.nestedPath + tokens.canonicalName,</span><br><span class="line">							<span class="string">"Cannot set element with index "</span> + index + <span class="string">" in List of size "</span> +</span><br><span class="line">							size + <span class="string">", accessed using property path '"</span> + tokens.canonicalName +</span><br><span class="line">							<span class="string">"': List does not support filling up gaps with null elements"</span>);</span><br><span class="line">				&#125;</span><br><span class="line">			&#125;</span><br><span class="line">			list.add(convertedValue);</span><br><span class="line">		&#125;</span><br><span class="line">		<span class="keyword">else</span> &#123;</span><br><span class="line">			<span class="keyword">try</span> &#123;</span><br><span class="line">				<span class="comment">//将值添加到list中</span></span><br><span class="line">				list.set(index, convertedValue);</span><br><span class="line">			&#125;</span><br><span class="line">			<span class="keyword">catch</span> (IndexOutOfBoundsException ex) &#123;</span><br><span class="line">				<span class="keyword">throw</span> <span class="keyword">new</span> InvalidPropertyException(getRootClass(), <span class="keyword">this</span>.nestedPath + tokens.canonicalName,</span><br><span class="line">						<span class="string">"Invalid list index in property path '"</span> + tokens.canonicalName + <span class="string">"'"</span>, ex);</span><br><span class="line">			&#125;</span><br><span class="line">		&#125;</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="comment">//注入map类型的属性值</span></span><br><span class="line">	<span class="keyword">else</span> <span class="keyword">if</span> (propValue <span class="keyword">instanceof</span> Map) &#123;</span><br><span class="line">		<span class="comment">//获取map集合key的类型</span></span><br><span class="line">		Class&lt;?&gt; mapKeyType = ph.getMapKeyType(tokens.keys.length);</span><br><span class="line">		<span class="comment">//获取map集合value的类型</span></span><br><span class="line">		Class&lt;?&gt; mapValueType = ph.getMapValueType(tokens.keys.length);</span><br><span class="line">		Map&lt;Object, Object&gt; map = (Map&lt;Object, Object&gt;) propValue;</span><br><span class="line">		<span class="comment">// IMPORTANT: Do not pass full property name in here - property editors</span></span><br><span class="line">		<span class="comment">// must not kick in for map keys but rather only for map values.</span></span><br><span class="line">		TypeDescriptor typeDescriptor = TypeDescriptor.valueOf(mapKeyType);</span><br><span class="line">		<span class="comment">//解析map类型属性key值</span></span><br><span class="line">		Object convertedMapKey = convertIfNecessary(<span class="keyword">null</span>, <span class="keyword">null</span>, lastKey, mapKeyType, typeDescriptor);</span><br><span class="line">		Object oldValue = <span class="keyword">null</span>;</span><br><span class="line">		<span class="keyword">if</span> (isExtractOldValueForEditor()) &#123;</span><br><span class="line">			oldValue = map.get(convertedMapKey);</span><br><span class="line">		&#125;</span><br><span class="line">		<span class="comment">// Pass full property name and old value in here, since we want full</span></span><br><span class="line">		<span class="comment">// conversion ability for map values.</span></span><br><span class="line">		<span class="comment">//解析map类型属性value值</span></span><br><span class="line">		Object convertedMapValue = convertIfNecessary(tokens.canonicalName, oldValue, pv.getValue(),</span><br><span class="line">				mapValueType, ph.nested(tokens.keys.length));</span><br><span class="line">		<span class="comment">//将解析后的key和value值赋值给map集合属性</span></span><br><span class="line">		map.put(convertedMapKey, convertedMapValue);</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="keyword">else</span> &#123;</span><br><span class="line">		<span class="keyword">throw</span> <span class="keyword">new</span> InvalidPropertyException(getRootClass(), <span class="keyword">this</span>.nestedPath + tokens.canonicalName,</span><br><span class="line">				<span class="string">"Property referenced in indexed property path '"</span> + tokens.canonicalName +</span><br><span class="line">				<span class="string">"' is neither an array nor a List nor a Map; returned value was ["</span> + propValue + <span class="string">"]"</span>);</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">private</span> <span class="keyword">void</span> <span class="title">processLocalProperty</span><span class="params">(PropertyTokenHolder tokens, PropertyValue pv)</span> </span>&#123;</span><br><span class="line">	PropertyHandler ph = getLocalPropertyHandler(tokens.actualName);</span><br><span class="line">	<span class="keyword">if</span> (ph == <span class="keyword">null</span> || !ph.isWritable()) &#123;</span><br><span class="line">		<span class="keyword">if</span> (pv.isOptional()) &#123;</span><br><span class="line">			<span class="keyword">if</span> (logger.isDebugEnabled()) &#123;</span><br><span class="line">				logger.debug(<span class="string">"Ignoring optional value for property '"</span> + tokens.actualName +</span><br><span class="line">						<span class="string">"' - property not found on bean class ["</span> + getRootClass().getName() + <span class="string">"]"</span>);</span><br><span class="line">			&#125;</span><br><span class="line">			<span class="keyword">return</span>;</span><br><span class="line">		&#125;</span><br><span class="line">		<span class="keyword">else</span> &#123;</span><br><span class="line">			<span class="keyword">throw</span> createNotWritablePropertyException(tokens.canonicalName);</span><br><span class="line">		&#125;</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	Object oldValue = <span class="keyword">null</span>;</span><br><span class="line">	<span class="keyword">try</span> &#123;</span><br><span class="line">		Object originalValue = pv.getValue();</span><br><span class="line">		Object valueToApply = originalValue;</span><br><span class="line">		<span class="keyword">if</span> (!Boolean.FALSE.equals(pv.conversionNecessary)) &#123;</span><br><span class="line">			<span class="keyword">if</span> (pv.isConverted()) &#123;</span><br><span class="line">				valueToApply = pv.getConvertedValue();</span><br><span class="line">			&#125;</span><br><span class="line">			<span class="keyword">else</span> &#123;</span><br><span class="line">				<span class="keyword">if</span> (isExtractOldValueForEditor() &amp;&amp; ph.isReadable()) &#123;</span><br><span class="line">					<span class="keyword">try</span> &#123;</span><br><span class="line">						oldValue = ph.getValue();</span><br><span class="line">					&#125;</span><br><span class="line">					<span class="keyword">catch</span> (Exception ex) &#123;</span><br><span class="line">						<span class="keyword">if</span> (ex <span class="keyword">instanceof</span> PrivilegedActionException) &#123;</span><br><span class="line">							ex = ((PrivilegedActionException) ex).getException();</span><br><span class="line">						&#125;</span><br><span class="line">						<span class="keyword">if</span> (logger.isDebugEnabled()) &#123;</span><br><span class="line">							logger.debug(<span class="string">"Could not read previous value of property '"</span> +</span><br><span class="line">									<span class="keyword">this</span>.nestedPath + tokens.canonicalName + <span class="string">"'"</span>, ex);</span><br><span class="line">						&#125;</span><br><span class="line">					&#125;</span><br><span class="line">				&#125;</span><br><span class="line">				valueToApply = convertForProperty(</span><br><span class="line">						tokens.canonicalName, oldValue, originalValue, ph.toTypeDescriptor());</span><br><span class="line">			&#125;</span><br><span class="line">			pv.getOriginalPropertyValue().conversionNecessary = (valueToApply != originalValue);</span><br><span class="line">		&#125;</span><br><span class="line">		ph.setValue(valueToApply);</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="keyword">catch</span> (TypeMismatchException ex) &#123;</span><br><span class="line">		<span class="keyword">throw</span> ex;</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="keyword">catch</span> (InvocationTargetException ex) &#123;</span><br><span class="line">		PropertyChangeEvent propertyChangeEvent = <span class="keyword">new</span> PropertyChangeEvent(</span><br><span class="line">				getRootInstance(), <span class="keyword">this</span>.nestedPath + tokens.canonicalName, oldValue, pv.getValue());</span><br><span class="line">		<span class="keyword">if</span> (ex.getTargetException() <span class="keyword">instanceof</span> ClassCastException) &#123;</span><br><span class="line">			<span class="keyword">throw</span> <span class="keyword">new</span> TypeMismatchException(propertyChangeEvent, ph.getPropertyType(), ex.getTargetException());</span><br><span class="line">		&#125;</span><br><span class="line">		<span class="keyword">else</span> &#123;</span><br><span class="line">			Throwable cause = ex.getTargetException();</span><br><span class="line">			<span class="keyword">if</span> (cause <span class="keyword">instanceof</span> UndeclaredThrowableException) &#123;</span><br><span class="line">				<span class="comment">// May happen e.g. with Groovy-generated methods</span></span><br><span class="line">				cause = cause.getCause();</span><br><span class="line">			&#125;</span><br><span class="line">			<span class="keyword">throw</span> <span class="keyword">new</span> MethodInvocationException(propertyChangeEvent, cause);</span><br><span class="line">		&#125;</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="keyword">catch</span> (Exception ex) &#123;</span><br><span class="line">		PropertyChangeEvent pce = <span class="keyword">new</span> PropertyChangeEvent(</span><br><span class="line">				getRootInstance(), <span class="keyword">this</span>.nestedPath + tokens.canonicalName, oldValue, pv.getValue());</span><br><span class="line">		<span class="keyword">throw</span> <span class="keyword">new</span> MethodInvocationException(pce, ex);</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><code>ph.setValue(valueToApply)</code>以<code>org.springframework.beans.DirectFieldAccessor.FieldPropertyHandler#setValue</code>的实现为例，最终使用反射设值。</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">@Override</span><br><span class="line">		public void setValue(@Nullable Object value) throws Exception &#123;</span><br><span class="line">			try &#123;</span><br><span class="line">				ReflectionUtils.makeAccessible(this.field);</span><br><span class="line">				this.field.set(getWrappedInstance(), value);</span><br><span class="line">			&#125;</span><br><span class="line">			catch (IllegalAccessException ex) &#123;</span><br><span class="line">				throw new InvalidPropertyException(getWrappedClass(), this.field.getName(),</span><br><span class="line">						&quot;Field is not accessible&quot;, ex);</span><br><span class="line">			&#125;</span><br><span class="line">		&#125;</span><br></pre></td></tr></table></figure>



<p>通过对上面注入依赖代码的分析，我们已经明白了Spring IoC容器是如何将属性的值注入到Bean实例对象中去的：</p>
<p>1）对于集合类型的属性，将其属性值解析为目标类型的集合后直接赋值给属性。</p>
<p>2）对于非集合类型的属性，大量使用了JDK的反射机制，通过属性的<code>getter()</code>方法获取指定属性注入以前的值，同时调用属性的<code>setter()</code>方法为属性设置注入后的值。</p>
<p>时序图如下</p>
<p><img src="https://tu.dxysun.com/%E4%B8%80%E6%AD%A5%E4%B8%80%E6%AD%A5%E6%89%8B%E7%BB%98Spring%20DI%E8%BF%90%E8%A1%8C%E6%97%B6%E5%BA%8F%E5%9B%BE-20210902233048.png" alt=""></p>
<h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><p>至此Spring IoC容器对Bean定义资源文件的定位，载入、解析和依赖注入已经全部分析完毕，现在Spring IoC容器中管理了一系列靠依赖关系联系起来的Bean，程序不需要应用自己手动创建所需的对象，SpringIoC容器会在我们使用的时候自动为我们创建，并且为我们注入好相关的依赖，这就是Spring核心功能的控制反转和依赖注入的相关功能。</p>
<h1 id="loC容器的细节"><a href="#loC容器的细节" class="headerlink" title="loC容器的细节"></a>loC容器的细节</h1><p>通过前面对Spring IoC容器的源码分析，我们已经基本上了解了Spring IoC容器对Bean定义资源的定位、载入和注册过程，同时也清楚了当用户通过<code>getBean()</code>方法向IoC容器获取被管理的 Bean时，IoC容器对Bean进行的初始化和依赖注入过程，这些是SpringIoC容器的基本功能特性。 </p>
<p>Spring IoC容器还有一些高级特性，如使用lazy-init属性对Bean预初始化、FactoryBean产生或者修饰Bean对象的生成、IoC容器初始化Bean过程中使用BeanPostProcessor后置处理器对Bean声明周期事件管理等。</p>
<h2 id="关于延时加载"><a href="#关于延时加载" class="headerlink" title="关于延时加载"></a>关于延时加载</h2><p>通过前面我们对IoC容器的实现和工作原理分析我们已经知道loC容器的初始化过程就是对Bean定义资源的定位、载入和注册，此时容器对Bean的依赖注入并没有发生，依赖注入主要是通过<code>getBean()</code>方法的调用完成。</p>
<p>当Bean定义资源的<code>&lt;Bean&gt;</code>元素中配置了<code>lazy-init=false</code>属性时，或者未配置懒加载的相关属性，容器将会在初始化的时候对所配置的Bean进行预实例化，Bean的依赖注入在容器初始化的时候就已经完成。这样，当应用程序第一次会向容器索取被管理的Bean时，就不用再初始化和对Bean进行依赖注入了，直接从容器中获取已经完成依赖注入的现成Bean，可以提高应用第一次向容器获取Bean的性能。</p>
<p>在<code>refresh()</code>方法中<code>ConfigurablelistableBeanFactorybeanFactory=obtainFreshBeanFactory();</code>启动了Bean定义资源的载入、注册过程，而<code>finishBeanFactorylnitialization</code>方法是对注册后的Bean定义中的预实例化<code>（lazy-init=false，Spring默认就是预实例化，即为false）</code>的Bean进行处理的地方。</p>
<h2 id="关于FactoryBean和BeanFactory"><a href="#关于FactoryBean和BeanFactory" class="headerlink" title="关于FactoryBean和BeanFactory"></a>关于FactoryBean和BeanFactory</h2><p>在Spring中，有两个很容易混淆的类：BeanFactory和FactoryBean。</p>
<p>BeanFactory ： Bean工厂，是一个工厂（Factory），我们Spring IoC容器的最顶层接口就是这个BeanFactory，它的作用是管理Bean，即实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。</p>
<p>FactoryBean：工厂Bean，是一个Bean，作用是产生其他bean实例。通常情况下，这种Bean 没有什么特别的要求，仅需要提供一个工厂方法，该方法用来返回其他Bean实例。通常情况下，Bean无须自己实现工厂模式，Spring容器担任工厂角色；但少数情况下，容器中的Bean本身就是工厂，其作用是产生其它Bean实例。</p>
<p>当用户使用容器本身时，可以使用转义字符”&amp;”来得到FactoryBean本身，以区别通过FactoryBean产生的实例对象和FactoryBean对象本身。在BeanFactory中通过如下代码定义了该转义字符：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">String FACTORY_ BEAN PREFIX = <span class="string">"&amp;"</span>;</span><br></pre></td></tr></table></figure>

<p>例如，如果myJndiObject是一个FactoryBean，则使用&amp;myJndiObject得到的是myJndiObject  FactoryBean对象，而不是myJndiObject产生出来的对象。</p>
<p>工厂Bean的实现类getObject方法创建Bean实例对象</p>
<p>FactoryBean的实现类有非常多，比如：Proxy、RM|、JNDI、ServletContextFactoryBean等等，FactoryBean接口为Spring容器提供了一个很好的封装机制，具体的getObject()有不同的实现类，根据不同的实现策略来具体提供。</p>
<h2 id="Autowired"><a href="#Autowired" class="headerlink" title="Autowired"></a>Autowired</h2><p>Spring IoC容器提供了两种管理Bean依赖关系的方式：</p>
<p>1）显式管理：通过BeanDefinition的属性值和构造方法实现Bean依赖关系管理。</p>
<p>2）Autowired：SpringloC容器的依赖自动装配功能，不需要对Bean属性的依赖关系做显式的声明，只需要在配置好Autowired属性，IoC容器会自动使用反射查找属性的类型和名称，然后基于属性的类型或者名称来自动匹配容器中管理的Bean，从而自动地完成依赖注入。</p>
<p>通过对Autowired自动装配特性的理解，我们知道容器对Bean的自动装配发生在容器对Bean依赖注入的过程中。</p>
<p>在前面对Spring loC容器的依赖注入过程源码分析中，我们已经知道了容器对Bean 实例对象的属性注入的处理发生在AbstractAutoWireCapableBeanFactory类中的<code>populateBean()</code>方法中，我们通过程序流程分析Autowired的实现原理：</p>
<p>1、AbstractAutoWireCapableBeanFactory对Bean实例进行属性依赖注入</p>
<p>第一次通过<code>getBean()</code>方法（配置了lazy-init预实例化属性的除外）向IoC容器索取Bean时，容器创建Bean实例对象，并且对Bean实例对象进行属性依赖注入</p>
<p><code>AbstractAutoWireCapableBeanFactory的populateBean()</code>方法就是实现Bean属性依赖注入的功能，可查看上面相关源码。</p>
<p>2、Spring IoC容器根据Bean名称或者类型进行autowiring自动依赖注入</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//根据类型对属性进行自动依赖注入</span></span><br><span class="line"><span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">autowireByType</span><span class="params">(</span></span></span><br><span class="line"><span class="function"><span class="params">		String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs)</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">	<span class="comment">//获取用户定义的类型转换器</span></span><br><span class="line">	TypeConverter converter = getCustomTypeConverter();</span><br><span class="line">	<span class="keyword">if</span> (converter == <span class="keyword">null</span>) &#123;</span><br><span class="line">		converter = bw;</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="comment">//存放解析的要注入的属性</span></span><br><span class="line">	Set&lt;String&gt; autowiredBeanNames = <span class="keyword">new</span> LinkedHashSet&lt;&gt;(<span class="number">4</span>);</span><br><span class="line">	<span class="comment">//对Bean对象中非简单属性(不是简单继承的对象，如8中原始类型，字符</span></span><br><span class="line">	<span class="comment">//URL等都是简单属性)进行处理</span></span><br><span class="line">	String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);</span><br><span class="line">	<span class="keyword">for</span> (String propertyName : propertyNames) &#123;</span><br><span class="line">		<span class="keyword">try</span> &#123;</span><br><span class="line">			<span class="comment">//获取指定属性名称的属性描述器</span></span><br><span class="line">			PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);</span><br><span class="line">			<span class="comment">// Don't try autowiring by type for type Object: never makes sense,</span></span><br><span class="line">			<span class="comment">// even if it technically is a unsatisfied, non-simple property.</span></span><br><span class="line">			<span class="comment">//不对Object类型的属性进行autowiring自动依赖注入</span></span><br><span class="line">			<span class="keyword">if</span> (Object<span class="class">.<span class="keyword">class</span> !</span>= pd.getPropertyType()) &#123;</span><br><span class="line">				<span class="comment">//获取属性的setter方法</span></span><br><span class="line">				MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);</span><br><span class="line">				<span class="comment">// Do not allow eager init for type matching in case of a prioritized post-processor.</span></span><br><span class="line">				<span class="comment">//检查指定类型是否可以被转换为目标对象的类型</span></span><br><span class="line">				<span class="keyword">boolean</span> eager = !PriorityOrdered<span class="class">.<span class="keyword">class</span>.<span class="title">isInstance</span>(<span class="title">bw</span>.<span class="title">getWrappedInstance</span>())</span>;</span><br><span class="line">				<span class="comment">//创建一个要被注入的依赖描述</span></span><br><span class="line">				DependencyDescriptor desc = <span class="keyword">new</span> AutowireByTypeDependencyDescriptor(methodParam, eager);</span><br><span class="line">				<span class="comment">//根据容器的Bean定义解析依赖关系，返回所有要被注入的Bean对象</span></span><br><span class="line">				Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);</span><br><span class="line">				<span class="keyword">if</span> (autowiredArgument != <span class="keyword">null</span>) &#123;</span><br><span class="line">					<span class="comment">//为属性赋值所引用的对象</span></span><br><span class="line">					pvs.add(propertyName, autowiredArgument);</span><br><span class="line">				&#125;</span><br><span class="line">				<span class="keyword">for</span> (String autowiredBeanName : autowiredBeanNames) &#123;</span><br><span class="line">					<span class="comment">//指定名称属性注册依赖Bean名称，进行属性依赖注入</span></span><br><span class="line">					registerDependentBean(autowiredBeanName, beanName);</span><br><span class="line">					<span class="keyword">if</span> (logger.isDebugEnabled()) &#123;</span><br><span class="line">						logger.debug(<span class="string">"Autowiring by type from bean name '"</span> + beanName + <span class="string">"' via property '"</span> +</span><br><span class="line">								propertyName + <span class="string">"' to bean named '"</span> + autowiredBeanName + <span class="string">"'"</span>);</span><br><span class="line">					&#125;</span><br><span class="line">				&#125;</span><br><span class="line">				<span class="comment">//释放已自动注入的属性</span></span><br><span class="line">				autowiredBeanNames.clear();</span><br><span class="line">			&#125;</span><br><span class="line">		&#125;</span><br><span class="line">		<span class="keyword">catch</span> (BeansException ex) &#123;</span><br><span class="line">			<span class="keyword">throw</span> <span class="keyword">new</span> UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);</span><br><span class="line">		&#125;</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>通过上面的源码分析，我们可以看出来通过属性名进行自动依赖注入的相对比通过属性类型进行自动依赖注入要稍微简单一些，但是真正实现属性注入的是DefaultSingletonBeanRegistry类的<code>registerDependentBean()</code>方法。</p>
<p>3、 DefaultSingletonBeanRegistry的 registerDependentBean方法对属性注入</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//为指定的Bean注入依赖的Bean</span></span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">registerDependentBean</span><span class="params">(String beanName, String dependentBeanName)</span> </span>&#123;</span><br><span class="line">		<span class="comment">// A quick check for an existing entry upfront, avoiding synchronization...</span></span><br><span class="line">		<span class="comment">//处理Bean名称，将别名转换为规范的Bean名称</span></span><br><span class="line">		String canonicalName = canonicalName(beanName);</span><br><span class="line">		Set&lt;String&gt; dependentBeans = <span class="keyword">this</span>.dependentBeanMap.get(canonicalName);</span><br><span class="line">		<span class="keyword">if</span> (dependentBeans != <span class="keyword">null</span> &amp;&amp; dependentBeans.contains(dependentBeanName)) &#123;</span><br><span class="line">			<span class="keyword">return</span>;</span><br><span class="line">		&#125;</span><br><span class="line"></span><br><span class="line">		<span class="comment">// No entry yet -&gt; fully synchronized manipulation of the dependentBeans Set</span></span><br><span class="line">		<span class="comment">//多线程同步，保证容器内数据的一致性</span></span><br><span class="line">		<span class="comment">//先从容器中：bean名称--&gt;全部依赖Bean名称集合找查找给定名称Bean的依赖Bean</span></span><br><span class="line">		<span class="keyword">synchronized</span> (<span class="keyword">this</span>.dependentBeanMap) &#123;</span><br><span class="line">			<span class="comment">//获取给定名称Bean的所有依赖Bean名称</span></span><br><span class="line">			dependentBeans = <span class="keyword">this</span>.dependentBeanMap.get(canonicalName);</span><br><span class="line">			<span class="keyword">if</span> (dependentBeans == <span class="keyword">null</span>) &#123;</span><br><span class="line">				<span class="comment">//为Bean设置依赖Bean信息</span></span><br><span class="line">				dependentBeans = <span class="keyword">new</span> LinkedHashSet&lt;&gt;(<span class="number">8</span>);</span><br><span class="line">				<span class="keyword">this</span>.dependentBeanMap.put(canonicalName, dependentBeans);</span><br><span class="line">			&#125;</span><br><span class="line">			<span class="comment">//向容器中：bean名称--&gt;全部依赖Bean名称集合添加Bean的依赖信息</span></span><br><span class="line">			<span class="comment">//即，将Bean所依赖的Bean添加到容器的集合中</span></span><br><span class="line">			dependentBeans.add(dependentBeanName);</span><br><span class="line">		&#125;</span><br><span class="line">		<span class="comment">//从容器中：bean名称--&gt;指定名称Bean的依赖Bean集合找查找给定名称Bean的依赖Bean</span></span><br><span class="line">		<span class="keyword">synchronized</span> (<span class="keyword">this</span>.dependenciesForBeanMap) &#123;</span><br><span class="line">			Set&lt;String&gt; dependenciesForBean = <span class="keyword">this</span>.dependenciesForBeanMap.get(dependentBeanName);</span><br><span class="line">			<span class="keyword">if</span> (dependenciesForBean == <span class="keyword">null</span>) &#123;</span><br><span class="line">				dependenciesForBean = <span class="keyword">new</span> LinkedHashSet&lt;&gt;(<span class="number">8</span>);</span><br><span class="line">				<span class="keyword">this</span>.dependenciesForBeanMap.put(dependentBeanName, dependenciesForBean);</span><br><span class="line">			&#125;</span><br><span class="line">			<span class="comment">//向容器中：bean名称--&gt;指定Bean的依赖Bean名称集合添加Bean的依赖信息</span></span><br><span class="line">			<span class="comment">//即，将Bean所依赖的Bean添加到容器的集合中</span></span><br><span class="line">			dependenciesForBean.add(canonicalName);</span><br><span class="line">		&#125;</span><br><span class="line">	&#125;</span><br></pre></td></tr></table></figure>

<p>通过对autowiring的源码分析，我们可以看出，autowiring的实现过程：</p>
<p>a、对Bean的属性代调用<code>getBean()</code>方法，完成依赖Bean的初始化和依赖注入。</p>
<p>b、将依赖Bean的属性引用设置到被依赖的Bean属性上。</p>
<p>C、将依赖Bean的名称和被依赖Bean的名称存储在IoC容器的集合中。 </p>
<p>Spring IoC容器的autowiring属性自动依赖注入是一个很方便的特性，可以简化开发时的配置，但是凡是都有两面性，自动属性依赖注入也有不足，首先，Bean的依赖关系在配置文件中无法很清楚地看出来，对于维护造成一定困难。其次，由于自动依赖注入是Spring容器自动执行的，容器是不会智能判断的，如果配置不当，将会带来无法预料的后果，所以自动依赖注入特性在使用时还是综合考虑。</p>
 
      <!-- reward -->
      
      <div id="reword-out">
        <div id="reward-btn">
          打赏
        </div>
      </div>
      
    </div>
    

    <!-- copyright -->
    
    <footer class="article-footer">
       
<div class="share-btn">
      <span class="share-sns share-outer">
        <i class="ri-share-forward-line"></i>
        分享
      </span>
      <div class="share-wrap">
        <i class="arrow"></i>
        <div class="share-icons">
          
          <a class="weibo share-sns" href="javascript:;" data-type="weibo">
            <i class="ri-weibo-fill"></i>
          </a>
          <a class="weixin share-sns wxFab" href="javascript:;" data-type="weixin">
            <i class="ri-wechat-fill"></i>
          </a>
          <a class="qq share-sns" href="javascript:;" data-type="qq">
            <i class="ri-qq-fill"></i>
          </a>
          <a class="douban share-sns" href="javascript:;" data-type="douban">
            <i class="ri-douban-line"></i>
          </a>
          <!-- <a class="qzone share-sns" href="javascript:;" data-type="qzone">
            <i class="icon icon-qzone"></i>
          </a> -->
          
          <a class="facebook share-sns" href="javascript:;" data-type="facebook">
            <i class="ri-facebook-circle-fill"></i>
          </a>
          <a class="twitter share-sns" href="javascript:;" data-type="twitter">
            <i class="ri-twitter-fill"></i>
          </a>
          <a class="google share-sns" href="javascript:;" data-type="google">
            <i class="ri-google-fill"></i>
          </a>
        </div>
      </div>
</div>

<div class="wx-share-modal">
    <a class="modal-close" href="javascript:;"><i class="ri-close-circle-line"></i></a>
    <p>扫一扫，分享到微信</p>
    <div class="wx-qrcode">
      <img src="//api.qrserver.com/v1/create-qr-code/?size=150x150&data=https://dxysun.com/2021/09/02/springForBean1/" alt="微信分享二维码">
    </div>
</div>

<div id="share-mask"></div>  
  <ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/spring/" rel="tag">spring</a></li></ul>

    </footer>
  </div>

   
  <nav class="article-nav">
    
      <a href="/2021/09/04/springForAop/" class="article-nav-link">
        <strong class="article-nav-caption">上一篇</strong>
        <div class="article-nav-title">
          
            spring核心之AOP原理
          
        </div>
      </a>
    
    
      <a href="/2021/08/30/springForIOCAnnotation/" class="article-nav-link">
        <strong class="article-nav-caption">下一篇</strong>
        <div class="article-nav-title">Spring核心之基于Annotation的IOC容器初始化</div>
      </a>
    
  </nav>

  
   
  
</article>

</section>
      <footer class="footer">
  <div class="outer">
    <ul>
      <li>
        Copyrights &copy;
        2015-2024
        <i class="ri-heart-fill heart_icon"></i> dxysun
      </li>
    </ul>
    <ul>
      <li>
        
        
        
        由 <a href="https://hexo.io" target="_blank">Hexo</a> 强力驱动
        <span class="division">|</span>
        主题 - <a href="https://github.com/Shen-Yu/hexo-theme-ayer" target="_blank">Ayer</a>
        
      </li>
    </ul>
    <ul>
      <li>
        
        
        <span>
  <span><i class="ri-user-3-fill"></i>访问人数:<span id="busuanzi_value_site_uv"></span></s>
  <span class="division">|</span>
  <span><i class="ri-eye-fill"></i>浏览次数:<span id="busuanzi_value_page_pv"></span></span>
</span>
        
      </li>
    </ul>
    <ul>
      
        <li>
          <a href="https://beian.miit.gov.cn" target="_black" rel="nofollow">豫ICP备17012675号-1</a>
        </li>
        
    </ul>
    <ul>
      
    </ul>
    <ul>
      <li>
        <!-- cnzz统计 -->
        
      </li>
    </ul>
  </div>
</footer>
      <div class="float_btns">
        <div class="totop" id="totop">
  <i class="ri-arrow-up-line"></i>
</div>

<div class="todark" id="todark">
  <i class="ri-moon-line"></i>
</div>

      </div>
    </main>
    <aside class="sidebar on">
      <button class="navbar-toggle"></button>
<nav class="navbar">
  
  <div class="logo">
    <a href="/"><img src="https://dxysun.com/static/logo.png" alt="迎着朝阳"></a>
  </div>
  
  <ul class="nav nav-main">
    
    <li class="nav-item">
      <a class="nav-item-link" href="/">主页</a>
    </li>
    
    <li class="nav-item">
      <a class="nav-item-link" href="/archives">归档</a>
    </li>
    
    <li class="nav-item">
      <a class="nav-item-link" href="/categories">分类</a>
    </li>
    
    <li class="nav-item">
      <a class="nav-item-link" href="/tags">标签</a>
    </li>
    
    <li class="nav-item">
      <a class="nav-item-link" href="/photos">相册</a>
    </li>
    
    <li class="nav-item">
      <a class="nav-item-link" href="/friends">友链</a>
    </li>
    
    <li class="nav-item">
      <a class="nav-item-link" href="/about">关于我</a>
    </li>
    
  </ul>
</nav>
<nav class="navbar navbar-bottom">
  <ul class="nav">
    <li class="nav-item">
      
      <a class="nav-item-link nav-item-search"  title="搜索">
        <i class="ri-search-line"></i>
      </a>
      
      
      <a class="nav-item-link" target="_blank" href="/atom.xml" title="RSS Feed">
        <i class="ri-rss-line"></i>
      </a>
      
    </li>
  </ul>
</nav>
<div class="search-form-wrap">
  <div class="local-search local-search-plugin">
  <input type="search" id="local-search-input" class="local-search-input" placeholder="Search...">
  <div id="local-search-result" class="local-search-result"></div>
</div>
</div>
    </aside>
    <script>
      if (window.matchMedia("(max-width: 768px)").matches) {
        document.querySelector('.content').classList.remove('on');
        document.querySelector('.sidebar').classList.remove('on');
      }
    </script>
    <div id="mask"></div>

<!-- #reward -->
<div id="reward">
  <span class="close"><i class="ri-close-line"></i></span>
  <p class="reward-p"><i class="ri-cup-line"></i>请我喝杯咖啡吧~</p>
  <div class="reward-box">
    
    <div class="reward-item">
      <img class="reward-img" src="https://tu.dxysun.com/alipay-20201219151322.jpg">
      <span class="reward-type">支付宝</span>
    </div>
    
    
    <div class="reward-item">
      <img class="reward-img" src="https://tu.dxysun.com/weixin-20201219151346.png">
      <span class="reward-type">微信</span>
    </div>
    
  </div>
</div>
    
<script src="/js/jquery-2.0.3.min.js"></script>


<script src="/js/lazyload.min.js"></script>

<!-- Tocbot -->


<script src="/js/tocbot.min.js"></script>

<script>
  tocbot.init({
    tocSelector: '.tocbot',
    contentSelector: '.article-entry',
    headingSelector: 'h1, h2, h3, h4, h5, h6',
    hasInnerContainers: true,
    scrollSmooth: true,
    scrollContainer: 'main',
    positionFixedSelector: '.tocbot',
    positionFixedClass: 'is-position-fixed',
    fixedSidebarOffset: 'auto'
  });
</script>

<script src="https://cdn.jsdelivr.net/npm/jquery-modal@0.9.2/jquery.modal.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/jquery-modal@0.9.2/jquery.modal.min.css">
<script src="https://cdn.jsdelivr.net/npm/justifiedGallery@3.7.0/dist/js/jquery.justifiedGallery.min.js"></script>

<script src="/dist/main.js"></script>

<!-- ImageViewer -->

<!-- Root element of PhotoSwipe. Must have class pswp. -->
<div class="pswp" tabindex="-1" role="dialog" aria-hidden="true">

    <!-- Background of PhotoSwipe. 
         It's a separate element as animating opacity is faster than rgba(). -->
    <div class="pswp__bg"></div>

    <!-- Slides wrapper with overflow:hidden. -->
    <div class="pswp__scroll-wrap">

        <!-- Container that holds slides. 
            PhotoSwipe keeps only 3 of them in the DOM to save memory.
            Don't modify these 3 pswp__item elements, data is added later on. -->
        <div class="pswp__container">
            <div class="pswp__item"></div>
            <div class="pswp__item"></div>
            <div class="pswp__item"></div>
        </div>

        <!-- Default (PhotoSwipeUI_Default) interface on top of sliding area. Can be changed. -->
        <div class="pswp__ui pswp__ui--hidden">

            <div class="pswp__top-bar">

                <!--  Controls are self-explanatory. Order can be changed. -->

                <div class="pswp__counter"></div>

                <button class="pswp__button pswp__button--close" title="Close (Esc)"></button>

                <button class="pswp__button pswp__button--share" style="display:none" title="Share"></button>

                <button class="pswp__button pswp__button--fs" title="Toggle fullscreen"></button>

                <button class="pswp__button pswp__button--zoom" title="Zoom in/out"></button>

                <!-- Preloader demo http://codepen.io/dimsemenov/pen/yyBWoR -->
                <!-- element will get class pswp__preloader--active when preloader is running -->
                <div class="pswp__preloader">
                    <div class="pswp__preloader__icn">
                        <div class="pswp__preloader__cut">
                            <div class="pswp__preloader__donut"></div>
                        </div>
                    </div>
                </div>
            </div>

            <div class="pswp__share-modal pswp__share-modal--hidden pswp__single-tap">
                <div class="pswp__share-tooltip"></div>
            </div>

            <button class="pswp__button pswp__button--arrow--left" title="Previous (arrow left)">
            </button>

            <button class="pswp__button pswp__button--arrow--right" title="Next (arrow right)">
            </button>

            <div class="pswp__caption">
                <div class="pswp__caption__center"></div>
            </div>

        </div>

    </div>

</div>

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/photoswipe.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/default-skin/default-skin.min.css">
<script src="https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/photoswipe.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/photoswipe-ui-default.min.js"></script>

<script>
    function viewer_init() {
        let pswpElement = document.querySelectorAll('.pswp')[0];
        let $imgArr = document.querySelectorAll(('.article-entry img:not(.reward-img)'))

        $imgArr.forEach(($em, i) => {
            $em.onclick = () => {
                // slider展开状态
                // todo: 这样不好，后面改成状态
                if (document.querySelector('.left-col.show')) return
                let items = []
                $imgArr.forEach(($em2, i2) => {
                    let img = $em2.getAttribute('data-idx', i2)
                    let src = $em2.getAttribute('data-target') || $em2.getAttribute('src')
                    let title = $em2.getAttribute('alt')
                    // 获得原图尺寸
                    const image = new Image()
                    image.src = src
                    items.push({
                        src: src,
                        w: image.width || $em2.width,
                        h: image.height || $em2.height,
                        title: title
                    })
                })
                var gallery = new PhotoSwipe(pswpElement, PhotoSwipeUI_Default, items, {
                    index: parseInt(i)
                });
                gallery.init()
            }
        })
    }
    viewer_init()
</script>

<!-- MathJax -->

<script type="text/x-mathjax-config">
  MathJax.Hub.Config({
      tex2jax: {
          inlineMath: [ ['$','$'], ["\\(","\\)"]  ],
          processEscapes: true,
          skipTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code']
      }
  });

  MathJax.Hub.Queue(function() {
      var all = MathJax.Hub.getAllJax(), i;
      for(i=0; i < all.length; i += 1) {
          all[i].SourceElement().parentNode.className += ' has-jax';
      }
  });
</script>

<script src="https://cdn.jsdelivr.net/npm/mathjax@2.7.6/unpacked/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<script>
  var ayerConfig = {
    mathjax: true
  }
</script>

<!-- Katex -->

<!-- busuanzi  -->


<script src="/js/busuanzi-2.3.pure.min.js"></script>


<!-- ClickLove -->

<!-- ClickBoom1 -->

<!-- ClickBoom2 -->

<!-- CodeCopy -->


<link rel="stylesheet" href="/css/clipboard.css">

<script src="https://cdn.jsdelivr.net/npm/clipboard@2/dist/clipboard.min.js"></script>
<script>
  function wait(callback, seconds) {
    var timelag = null;
    timelag = window.setTimeout(callback, seconds);
  }
  !function (e, t, a) {
    var initCopyCode = function(){
      var copyHtml = '';
      copyHtml += '<button class="btn-copy" data-clipboard-snippet="">';
      copyHtml += '<i class="ri-file-copy-2-line"></i><span>COPY</span>';
      copyHtml += '</button>';
      $(".highlight .code pre").before(copyHtml);
      $(".article pre code").before(copyHtml);
      var clipboard = new ClipboardJS('.btn-copy', {
        target: function(trigger) {
          return trigger.nextElementSibling;
        }
      });
      clipboard.on('success', function(e) {
        let $btn = $(e.trigger);
        $btn.addClass('copied');
        let $icon = $($btn.find('i'));
        $icon.removeClass('ri-file-copy-2-line');
        $icon.addClass('ri-checkbox-circle-line');
        let $span = $($btn.find('span'));
        $span[0].innerText = 'COPIED';
        
        wait(function () { // 等待两秒钟后恢复
          $icon.removeClass('ri-checkbox-circle-line');
          $icon.addClass('ri-file-copy-2-line');
          $span[0].innerText = 'COPY';
        }, 2000);
      });
      clipboard.on('error', function(e) {
        e.clearSelection();
        let $btn = $(e.trigger);
        $btn.addClass('copy-failed');
        let $icon = $($btn.find('i'));
        $icon.removeClass('ri-file-copy-2-line');
        $icon.addClass('ri-time-line');
        let $span = $($btn.find('span'));
        $span[0].innerText = 'COPY FAILED';
        
        wait(function () { // 等待两秒钟后恢复
          $icon.removeClass('ri-time-line');
          $icon.addClass('ri-file-copy-2-line');
          $span[0].innerText = 'COPY';
        }, 2000);
      });
    }
    initCopyCode();
  }(window, document);
</script>


<!-- CanvasBackground -->


<script src="/js/dz.js"></script>



    
  </div>
</body>

</html>